Removed extraneous semicolons

This commit is contained in:
Waleed Latif
2025-01-28 10:40:38 -08:00
parent c71b6aa18f
commit f0f88dec5d
17 changed files with 548 additions and 548 deletions
+65 -65
View File
@@ -1,15 +1,15 @@
import { Edge } from 'reactflow';
import { Serializer } from '../index';
import { SerializedWorkflow } from '../types';
import { BlockState } from '@/stores/workflow/types';
import { OutputType } from '@/blocks/types';
import { Edge } from 'reactflow'
import { Serializer } from '../index'
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', () => ({
@@ -35,7 +35,7 @@ jest.mock('@/blocks', () => ({
},
subBlocks: []
}
};
}
}
// Default agent block config
return {
@@ -60,24 +60,24 @@ jest.mock('@/blocks', () => ({
},
subBlocks: []
}
};
}
},
getBlockTypeForTool: (toolId: string) => {
const toolToType: Record<string, string> = {
'openai.chat': 'agent',
'http.request': 'api',
'function': 'function'
};
return toolToType[toolId];
}
return toolToType[toolId]
}
}));
}))
describe('Serializer', () => {
let serializer: Serializer;
let serializer: Serializer
beforeEach(() => {
serializer = new Serializer();
});
serializer = new Serializer()
})
describe('serializeWorkflow', () => {
it('should serialize a workflow with agent and http blocks', () => {
@@ -125,7 +125,7 @@ describe('Serializer', () => {
},
outputType: 'json'
}
};
}
const connections: Edge[] = [
{
@@ -135,34 +135,34 @@ describe('Serializer', () => {
sourceHandle: 'response',
targetHandle: 'body'
}
];
]
const serialized = serializer.serializeWorkflow(blocks, connections);
const serialized = serializer.serializeWorkflow(blocks, connections)
// Test workflow structure
expect(serialized.version).toBe('1.0');
expect(serialized.blocks).toHaveLength(2);
expect(serialized.connections).toHaveLength(1);
expect(serialized.version).toBe('1.0')
expect(serialized.blocks).toHaveLength(2)
expect(serialized.connections).toHaveLength(1)
// Test agent block serialization
const agentBlock = serialized.blocks.find(b => b.id === 'agent-1');
expect(agentBlock).toBeDefined();
expect(agentBlock?.config.tool).toBe('openai.chat');
const agentBlock = serialized.blocks.find(b => b.id === 'agent-1')
expect(agentBlock).toBeDefined()
expect(agentBlock?.config.tool).toBe('openai.chat')
expect(agentBlock?.config.params).toEqual({
model: 'gpt-4o',
systemPrompt: 'You are helpful',
temperature: 0.7
});
})
// Test http block serialization
const httpBlock = serialized.blocks.find(b => b.id === 'http-1');
expect(httpBlock).toBeDefined();
expect(httpBlock?.config.tool).toBe('http.request');
const httpBlock = serialized.blocks.find(b => b.id === 'http-1')
expect(httpBlock).toBeDefined()
expect(httpBlock?.config.tool).toBe('http.request')
expect(httpBlock?.config.params).toEqual({
url: 'https://api.example.com',
method: 'GET'
});
});
})
})
it('should handle blocks with minimal required configuration', () => {
const blocks: Record<string, BlockState> = {
@@ -180,15 +180,15 @@ describe('Serializer', () => {
},
outputType: 'string'
}
};
}
const serialized = serializer.serializeWorkflow(blocks, []);
const block = serialized.blocks[0];
const serialized = serializer.serializeWorkflow(blocks, [])
const block = serialized.blocks[0]
expect(block.id).toBe('minimal-1');
expect(block.config.tool).toBe('openai.chat');
expect(block.config.params).toEqual({ model: 'gpt-4o' });
});
expect(block.id).toBe('minimal-1')
expect(block.config.tool).toBe('openai.chat')
expect(block.config.params).toEqual({ model: 'gpt-4o' })
})
it('should handle complex workflow with multiple interconnected blocks', () => {
const blocks: Record<string, BlockState> = {
@@ -249,7 +249,7 @@ describe('Serializer', () => {
},
outputType: 'json'
}
};
}
const connections: Edge[] = [
{
@@ -266,22 +266,22 @@ describe('Serializer', () => {
sourceHandle: 'result',
targetHandle: 'body'
}
];
]
const serialized = serializer.serializeWorkflow(blocks, connections);
const serialized = serializer.serializeWorkflow(blocks, connections)
// Verify workflow structure
expect(serialized.blocks).toHaveLength(3);
expect(serialized.connections).toHaveLength(2);
expect(serialized.blocks).toHaveLength(3)
expect(serialized.connections).toHaveLength(2)
// Verify data flow chain
const conn1 = serialized.connections[0];
const conn2 = serialized.connections[1];
expect(conn1.source).toBe('input-1');
expect(conn1.target).toBe('process-1');
expect(conn2.source).toBe('process-1');
expect(conn2.target).toBe('output-1');
});
const conn1 = serialized.connections[0]
const conn2 = serialized.connections[1]
expect(conn1.source).toBe('input-1')
expect(conn1.target).toBe('process-1')
expect(conn2.source).toBe('process-1')
expect(conn2.target).toBe('output-1')
})
it('should preserve tool-specific parameters', () => {
const blocks: Record<string, BlockState> = {
@@ -309,19 +309,19 @@ describe('Serializer', () => {
},
outputType: 'string'
}
};
}
const serialized = serializer.serializeWorkflow(blocks, []);
const block = serialized.blocks[0];
const serialized = serializer.serializeWorkflow(blocks, [])
const block = serialized.blocks[0]
expect(block.config.tool).toBe('openai.chat');
expect(block.config.tool).toBe('openai.chat')
expect(block.config.params).toEqual({
model: 'gpt-4o',
temperature: 0.7,
maxTokens: 1000
});
});
});
})
})
})
describe('deserializeWorkflow', () => {
it('should deserialize a workflow back to blocks and connections', () => {
@@ -345,15 +345,15 @@ describe('Serializer', () => {
}
],
connections: []
};
}
const { blocks } = serializer.deserializeWorkflow(workflow);
const block = blocks['agent-1'];
const { blocks } = serializer.deserializeWorkflow(workflow)
const block = blocks['agent-1']
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');
});
});
});
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')
})
})
})
+32 -32
View File
@@ -1,8 +1,8 @@
import { BlockState, SubBlockState } from '@/stores/workflow/types';
import { Edge } from 'reactflow';
import { SerializedBlock, SerializedConnection, SerializedWorkflow } from './types';
import { getBlock, getBlockTypeForTool } from '@/blocks';
import { OutputType, SubBlockType } from '@/blocks/types';
import { BlockState, SubBlockState } from '@/stores/workflow/types'
import { Edge } from 'reactflow'
import { SerializedBlock, SerializedConnection, SerializedWorkflow } from './types'
import { getBlock, getBlockTypeForTool } from '@/blocks'
import { OutputType, SubBlockType } from '@/blocks/types'
export class Serializer {
serializeWorkflow(blocks: Record<string, BlockState>, connections: Edge[]): SerializedWorkflow {
@@ -15,33 +15,33 @@ export class Serializer {
sourceHandle: conn.sourceHandle || undefined,
targetHandle: conn.targetHandle || undefined
}))
};
}
}
private serializeBlock(block: BlockState): SerializedBlock {
const blockConfig = getBlock(block.type);
const blockConfig = getBlock(block.type)
if (!blockConfig) {
throw new Error(`Block configuration not found for type: ${block.type}`);
throw new Error(`Block configuration not found for type: ${block.type}`)
}
// Get the tool ID from the block's configuration
const tools = blockConfig.tools;
const tools = blockConfig.tools
if (!tools?.access || tools.access.length === 0) {
throw new Error(`No tools specified for block type: ${block.type}`);
throw new Error(`No tools specified for block type: ${block.type}`)
}
// Get all values from subBlocks
const params: Record<string, any> = {};
const params: Record<string, any> = {}
Object.entries(block.subBlocks || {}).forEach(([id, subBlock]) => {
if (subBlock?.value !== undefined) {
params[id] = subBlock.value;
params[id] = subBlock.value
}
});
})
// Get the tool ID from the block's configuration
const toolId = tools.config?.tool?.(params) || params.tool || tools.access[0];
const toolId = tools.config?.tool?.(params) || params.tool || tools.access[0]
if (!toolId || !tools.access.includes(toolId)) {
throw new Error(`Invalid or unauthorized tool: ${toolId}`);
throw new Error(`Invalid or unauthorized tool: ${toolId}`)
}
return {
@@ -57,18 +57,18 @@ export class Serializer {
}
}
}
};
}
}
deserializeWorkflow(serialized: SerializedWorkflow): {
blocks: Record<string, BlockState>;
connections: Edge[];
blocks: Record<string, BlockState>
connections: Edge[]
} {
const blocks: Record<string, BlockState> = {};
const blocks: Record<string, BlockState> = {}
serialized.blocks.forEach(block => {
const deserialized = this.deserializeBlock(block);
blocks[deserialized.id] = deserialized;
});
const deserialized = this.deserializeBlock(block)
blocks[deserialized.id] = deserialized
})
return {
blocks,
@@ -79,20 +79,20 @@ export class Serializer {
sourceHandle: conn.sourceHandle || null,
targetHandle: conn.targetHandle || null
}))
};
}
}
private deserializeBlock(serialized: SerializedBlock): BlockState {
const toolId = serialized.config.tool;
const blockType = getBlockTypeForTool(toolId);
const toolId = serialized.config.tool
const blockType = getBlockTypeForTool(toolId)
if (!blockType) {
throw new Error(`Could not determine block type for tool: ${toolId}`);
throw new Error(`Could not determine block type for tool: ${toolId}`)
}
const blockConfig = getBlock(blockType);
const blockConfig = getBlock(blockType)
if (!blockConfig) {
throw new Error(`Block configuration not found for type: ${blockType}`);
throw new Error(`Block configuration not found for type: ${blockType}`)
}
return {
@@ -101,15 +101,15 @@ export class Serializer {
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);
const subBlock = blockConfig.workflow.subBlocks?.find(sb => sb.id === key)
acc[key] = {
id: key,
type: subBlock?.type || 'short-input',
value: value
};
return acc;
}
return acc
}, {} as Record<string, SubBlockState>),
outputType: serialized.config.interface.outputs.output as OutputType
};
}
}
}
+23 -23
View File
@@ -1,39 +1,39 @@
export interface SerializedWorkflow {
version: string;
blocks: SerializedBlock[];
connections: SerializedConnection[];
version: string
blocks: SerializedBlock[]
connections: SerializedConnection[]
}
export interface SerializedConnection {
source: string;
target: string;
sourceHandle?: string;
targetHandle?: string;
source: string
target: string
sourceHandle?: string
targetHandle?: string
}
export interface Position {
x: number;
y: number;
x: number
y: number
}
export interface BlockConfig {
tool: string;
params: Record<string, any>;
tool: string
params: Record<string, any>
interface: {
inputs: Record<string, string>;
outputs: Record<string, string>;
};
inputs: Record<string, string>
outputs: Record<string, string>
}
}
export interface SerializedBlock {
id: string;
position: Position;
config: BlockConfig;
id: string
position: Position
config: BlockConfig
metadata?: {
title?: string;
description?: string;
category?: string;
icon?: string;
color?: string;
};
title?: string
description?: string
category?: string
icon?: string
color?: string
}
}