-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Expand file tree
/
Copy pathfunction.ts
More file actions
108 lines (100 loc) · 5.25 KB
/
Copy pathfunction.ts
File metadata and controls
108 lines (100 loc) · 5.25 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
107
108
import { CodeIcon } from '@/components/icons'
import { CodeLanguage, getLanguageDisplayName } from '@/lib/execution/languages'
import type { BlockConfig } from '@/blocks/types'
import type { CodeExecutionOutput } from '@/tools/function/types'
export const FunctionBlock: BlockConfig<CodeExecutionOutput> = {
type: 'function',
name: 'Function',
description: 'Run custom logic',
longDescription:
'This is a core workflow block. Execute custom JavaScript or Python code within your workflow. JavaScript without imports runs locally for fast execution, while code with imports or Python uses E2B sandbox.',
bestPractices: `
- JavaScript code without external imports runs in a local VM for fastest execution.
- JavaScript code with import/require statements requires E2B and runs in a secure sandbox.
- Python code always requires E2B and runs in a secure sandbox.
- Can reference workflow variables using <blockName.output> syntax as usual within code. Avoid XML/HTML tags.
`,
docsLink: 'https://docs.sim.ai/workflows/blocks/function',
category: 'blocks',
bgColor: '#FF402F',
icon: CodeIcon,
subBlocks: [
{
id: 'language',
type: 'dropdown',
options: [
{ label: getLanguageDisplayName(CodeLanguage.JavaScript), id: CodeLanguage.JavaScript },
{ label: getLanguageDisplayName(CodeLanguage.Python), id: CodeLanguage.Python },
],
placeholder: 'Select language',
value: () => CodeLanguage.JavaScript,
showWhenEnvSet: 'NEXT_PUBLIC_E2B_ENABLED',
},
{
id: 'code',
title: 'Code',
type: 'code',
wandConfig: {
enabled: true,
maintainHistory: true,
prompt: `You are an expert JavaScript programmer.
Generate ONLY the raw body of a JavaScript function based on the user's request. Never wrap in markdown formatting.
The code should be executable within an 'async function(params, environmentVariables) {...}' context.
- 'params' (object): Contains input parameters derived from the JSON schema. Access these directly using the parameter name wrapped in angle brackets, e.g., '<paramName>'. Do NOT use 'params.paramName'.
- 'environmentVariables' (object): Contains environment variables. Reference these using the double curly brace syntax: '{{ENV_VAR_NAME}}'. Do NOT use 'environmentVariables.VAR_NAME' or env.
Current code context: {context}
IMPORTANT FORMATTING RULES:
1. Reference Environment Variables: Use the exact syntax {{VARIABLE_NAME}}. Do NOT wrap it in quotes (e.g., use 'apiKey = {{SERVICE_API_KEY}}' not 'apiKey = "{{SERVICE_API_KEY}}"'). Our system replaces these placeholders before execution.
2. Reference Input Parameters/Workflow Variables: Use the exact syntax <variable_name>. Do NOT wrap it in quotes (e.g., use 'userId = <userId>;' not 'userId = "<userId>";'). This includes parameters defined in the block's schema and outputs from previous blocks.
3. Function Body ONLY: Do NOT include the function signature (e.g., 'async function myFunction() {' or the surrounding '}').
4. Imports: Do NOT include import/require statements unless they are standard Node.js built-in modules (e.g., 'crypto', 'fs'). External libraries are not supported in this context.
5. Output: Ensure the code returns a value if the function is expected to produce output. Use 'return'.
6. Clarity: Write clean, readable code.
7. No Explanations: Do NOT include markdown formatting, comments explaining the rules, or any text other than the raw JavaScript code for the function body.
Example Scenario:
User Prompt: "Fetch user data from an API. Use the User ID passed in as 'userId' and an API Key stored as the 'SERVICE_API_KEY' environment variable."
Generated Code:
const userId = <block.content>; // Correct: Accessing input parameter without quotes
const apiKey = {{SERVICE_API_KEY}}; // Correct: Accessing environment variable without quotes
const url = \`https://api.example.com/users/\${userId}\`;
try {
const response = await fetch(url, {
method: 'GET',
headers: {
'Authorization': \`Bearer \${apiKey}\`,
'Content-Type': 'application/json'
}
});
if (!response.ok) {
// Throwing an error will mark the block execution as failed
throw new Error(\`API request failed with status \${response.status}: \${await response.text()}\`);
}
const data = await response.json();
console.log('User data fetched successfully.'); // Optional: logging for debugging
return data; // Return the fetched data which becomes the block's output
} catch (error) {
console.error(\`Error fetching user data: \${error.message}\`);
// Re-throwing the error ensures the workflow knows this step failed.
throw error;
}`,
placeholder: 'Describe the function you want to create...',
generationType: 'javascript-function-body',
},
},
],
tools: {
access: ['function_execute'],
},
inputs: {
code: { type: 'string', description: 'JavaScript or Python code to execute' },
language: { type: 'string', description: 'Language (javascript or python)' },
timeout: { type: 'number', description: 'Execution timeout' },
},
outputs: {
result: { type: 'json', description: 'Return value from the executed JavaScript function' },
stdout: {
type: 'string',
description: 'Console log output and debug messages from function execution',
},
},
}