-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Expand file tree
/
Copy pathexecute.ts
More file actions
106 lines (95 loc) · 2.97 KB
/
execute.ts
File metadata and controls
106 lines (95 loc) · 2.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import type { ToolConfig } from '../types'
import type { CodeExecutionInput, CodeExecutionOutput } from './types'
const DEFAULT_TIMEOUT = 10000 // 10 seconds
export const functionExecuteTool: ToolConfig<CodeExecutionInput, CodeExecutionOutput> = {
id: 'function_execute',
name: 'Function Execute',
description:
'Execute JavaScript code in a secure, sandboxed environment with proper isolation and resource limits.',
version: '1.0.0',
params: {
code: {
type: 'string',
required: true,
description: 'The code to execute',
},
timeout: {
type: 'number',
required: false,
description: 'Execution timeout in milliseconds',
default: DEFAULT_TIMEOUT,
},
envVars: {
type: 'object',
required: false,
description: 'Environment variables to make available during execution',
default: {},
},
blockData: {
type: 'object',
required: false,
description: 'Block output data for variable resolution',
default: {},
},
blockNameMapping: {
type: 'object',
required: false,
description: 'Mapping of block names to block IDs',
default: {},
},
},
request: {
url: '/api/function/execute',
method: 'POST',
headers: () => ({
'Content-Type': 'application/json',
}),
body: (params: CodeExecutionInput) => {
const codeContent = Array.isArray(params.code)
? params.code.map((c: { content: string }) => c.content).join('\n')
: params.code
return {
code: codeContent,
timeout: params.timeout || DEFAULT_TIMEOUT,
envVars: params.envVars || {},
blockData: params.blockData || {},
blockNameMapping: params.blockNameMapping || {},
workflowId: params._context?.workflowId,
isCustomTool: params.isCustomTool || false,
}
},
isInternalRoute: true,
},
transformResponse: async (response: Response): Promise<CodeExecutionOutput> => {
const result = await response.json()
if (!response.ok || !result.success) {
// Create enhanced error with debug information if available
const error = new Error(result.error || 'Code execution failed')
// Add debug information to the error object if available
if (result.debug) {
Object.assign(error, {
line: result.debug.line,
column: result.debug.column,
errorType: result.debug.errorType,
stack: result.debug.stack,
enhancedError: true,
})
}
throw error
}
return {
success: true,
output: {
result: result.output.result,
stdout: result.output.stdout,
},
}
},
transformError: (error: any) => {
// If we have enhanced error information, create a more detailed message
if (error.enhancedError && error.line) {
return `Line ${error.line}${error.column ? `:${error.column}` : ''} - ${error.message}`
}
return error.message || 'Code execution failed'
},
}