diff --git a/blocks/blocks/function.ts b/blocks/blocks/function.ts index 2a628ca070..7cfb9c33a7 100644 --- a/blocks/blocks/function.ts +++ b/blocks/blocks/function.ts @@ -11,20 +11,21 @@ export const FunctionBlock: BlockConfig = { category: 'advanced', }, tools: { - access: ['function'] + access: ['function.execute'], + config: { + tool: () => 'function.execute' + } }, workflow: { outputType: 'json', - inputs: { - code: 'string' - }, subBlocks: [ { id: 'code', title: 'Code', type: 'code', layout: 'full', - }, - ], - }, + placeholder: 'Enter your code here...' + } + ] + } } \ No newline at end of file diff --git a/tools/function/execute.ts b/tools/function/execute.ts new file mode 100644 index 0000000000..022cc9eff3 --- /dev/null +++ b/tools/function/execute.ts @@ -0,0 +1,85 @@ +import { ToolConfig, ToolResponse } from '../types' + +interface CodeExecutionInput { + code: Array<{content: string, id: string}> | string + input?: Record +} + +interface CodeExecutionOutput extends ToolResponse { + output: Record +} + +export const functionExecuteTool: ToolConfig = { + id: 'function.execute', + name: 'Function Execute', + description: 'Execute code in a sandboxed environment', + version: '1.0.0', + + params: { + code: { + type: 'string', + required: true, + description: 'The code to execute', + } + }, + + request: { + url: 'https://emkc.org/api/v2/piston/execute', + method: 'POST', + headers: () => ({ + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }), + body: (params) => { + const codeContent = Array.isArray(params.code) + ? params.code.map(c => c.content).join('\n') + : params.code; + + return { + language: 'js', + version: '*', + files: [{ + name: 'code.js', + content: codeContent + }], + stdin: '', + args: [], + compile_timeout: 10000, + run_timeout: 3000, + compile_memory_limit: -1, + run_memory_limit: -1 + }; + }, + }, + + transformResponse: async (response) => { + const result = await response.json(); + + if (!response.ok) { + throw new Error(result.message || 'Execution failed'); + } + + if (result.run?.stderr) { + throw new Error(result.run.stderr); + } + + const stdout = result.run?.stdout || ''; + + try { + // Try parsing the output as JSON + const parsed = JSON.parse(stdout); + return { output: parsed }; + } catch { + // If not JSON, wrap it in a JSON object + return { + output: { + result: stdout + } + }; + } + }, + + transformError: (error: any) => { + return error.message || 'Code execution failed'; + }, +} \ No newline at end of file diff --git a/tools/index.ts b/tools/index.ts index 005551c8c1..b9dba82a41 100644 --- a/tools/index.ts +++ b/tools/index.ts @@ -6,6 +6,7 @@ import { chatTool as xaiChat } from './xai/chat'; 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'; // Registry of all available tools export const tools: Record = { @@ -18,7 +19,9 @@ export const tools: Record = { 'http.request': httpRequest, // CRM Tools 'hubspot.contacts': hubspotContacts, - 'salesforce.opportunities': salesforceOpportunities + 'salesforce.opportunities': salesforceOpportunities, + // Function Tools + 'function.execute': functionExecute, }; // Get a tool by its ID