-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Expand file tree
/
Copy pathexecute.ts
More file actions
208 lines (198 loc) · 7.07 KB
/
Copy pathexecute.ts
File metadata and controls
208 lines (198 loc) · 7.07 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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
import {
normalizeRecord,
normalizeRecordMap,
normalizeStringRecord,
normalizeWorkflowVariables,
} from '@/lib/core/utils/records'
import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/execution/constants'
import { DEFAULT_CODE_LANGUAGE } from '@/lib/execution/languages'
import type { CodeExecutionInput, CodeExecutionOutput } from '@/tools/function/types'
import type { ToolConfig } from '@/tools/types'
export const functionExecuteTool: ToolConfig<CodeExecutionInput, CodeExecutionOutput> = {
id: 'function_execute',
name: 'Function Execute',
description:
'Execute JavaScript, Python, or shell scripts in a secure sandbox. For JS: fetch() is available, code runs in async IIFE wrapper. For shell: workspace env vars available as $VAR_NAME, pre-installed CLI tools (jq, curl, awscli, psql, gh, etc.). Use outputPath/outputTable to persist returned data, or outputSandboxPath + outputPath to export a file created inside the sandbox into the workspace.',
version: '1.0.0',
params: {
code: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description:
'Raw JavaScript statements (NOT a function). Code is auto-wrapped in async context. MUST use fetch() for HTTP (NOT xhr/axios/request libs). Write like: await fetch(url) then return result. NO import/require statements.',
},
language: {
type: 'string',
required: false,
visibility: 'user-only',
description: 'Language to execute (javascript, python, or shell)',
default: DEFAULT_CODE_LANGUAGE,
},
timeout: {
type: 'number',
required: false,
visibility: 'hidden',
description: 'Execution timeout in milliseconds',
default: DEFAULT_EXECUTION_TIMEOUT_MS,
},
title: {
type: 'string',
required: false,
visibility: 'hidden',
description: 'Short user-visible label for this execution.',
},
outputPath: {
type: 'string',
required: false,
visibility: 'hidden',
description:
'Write the tool result back to a workspace file, e.g. "files/result.json" or "files/report.csv". Use for text/JSON/CSV/markdown/html outputs.',
},
outputFormat: {
type: 'string',
required: false,
visibility: 'hidden',
description: 'Optional format override for outputPath (json, csv, txt, md, html).',
},
outputTable: {
type: 'string',
required: false,
visibility: 'hidden',
description:
'Overwrite a workspace table with the code result. The code must return an array of objects.',
},
outputSandboxPath: {
type: 'string',
required: false,
visibility: 'hidden',
description:
'Export a file created inside the sandbox to the workspace. Provide the sandbox file path here and also set outputPath to the workspace destination.',
},
outputMimeType: {
type: 'string',
required: false,
visibility: 'hidden',
description:
'MIME type for the exported file. Required for binary files (e.g. "image/png", "application/pdf"). If omitted, inferred from outputPath extension for text formats.',
},
overwriteFileId: {
type: 'string',
required: false,
visibility: 'hidden',
description:
'Overwrite this existing workspace file ID instead of creating a duplicate output file.',
},
envVars: {
type: 'object',
required: false,
visibility: 'hidden',
description: 'Environment variables to make available during execution',
default: {},
},
blockData: {
type: 'object',
required: false,
visibility: 'hidden',
description: 'Block output data for variable resolution',
default: {},
},
blockNameMapping: {
type: 'object',
required: false,
visibility: 'hidden',
description: 'Mapping of block names to block IDs',
default: {},
},
blockOutputSchemas: {
type: 'object',
required: false,
visibility: 'hidden',
description: 'Mapping of block IDs to their output schemas for validation',
default: {},
},
workflowVariables: {
type: 'object',
required: false,
visibility: 'hidden',
description: 'Workflow variables for <variable.name> resolution',
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
const body: Record<string, unknown> = {
code: codeContent,
sourceCode: params.sourceCode,
language: params.language || DEFAULT_CODE_LANGUAGE,
timeout: params.timeout || DEFAULT_EXECUTION_TIMEOUT_MS,
title: params.title,
outputPath: params.outputPath,
outputFormat: params.outputFormat,
outputTable: params.outputTable,
outputSandboxPath: params.outputSandboxPath,
outputMimeType: params.outputMimeType,
overwriteFileId: params.overwriteFileId,
inputs: params.inputs,
outputs: params.outputs,
envVars: normalizeStringRecord(params.envVars),
workflowVariables: normalizeWorkflowVariables(params.workflowVariables),
blockData: normalizeRecord(params.blockData),
blockNameMapping: normalizeStringRecord(params.blockNameMapping),
blockOutputSchemas: normalizeRecordMap(params.blockOutputSchemas),
contextVariables: normalizeRecord(params.contextVariables),
workflowId: params._context?.workflowId,
executionId: params._context?.executionId,
largeValueExecutionIds: params._context?.largeValueExecutionIds,
largeValueKeys: params._context?.largeValueKeys,
fileKeys: params._context?.fileKeys,
allowLargeValueWorkflowScope: params._context?.allowLargeValueWorkflowScope,
userId: params._context?.userId,
workspaceId: params._context?.workspaceId,
isCustomTool: params.isCustomTool || false,
}
if (params._sandboxFiles) {
body._sandboxFiles = params._sandboxFiles
}
return body
},
},
transformResponse: async (response: Response): Promise<CodeExecutionOutput> => {
const result = await response.json()
if (!result.success) {
return {
success: false,
output: {
result: null,
stdout: result.output?.stdout || '',
},
error: result.error,
resources: result.resources,
largeValueKeys: result.largeValueKeys,
fileKeys: result.fileKeys,
}
}
return {
success: true,
output: {
result: result.output.result,
stdout: result.output.stdout,
},
resources: result.resources,
largeValueKeys: result.largeValueKeys,
fileKeys: result.fileKeys,
}
},
outputs: {
result: { type: 'string', description: 'The result of the code execution' },
stdout: { type: 'string', description: 'The standard output of the code execution' },
},
}