diff --git a/apps/sim/app/api/function/execute/route.ts b/apps/sim/app/api/function/execute/route.ts index 31a5340d463..d1dc9190aab 100644 --- a/apps/sim/app/api/function/execute/route.ts +++ b/apps/sim/app/api/function/execute/route.ts @@ -1,6 +1,7 @@ import { createContext, Script } from 'vm' import { type NextRequest, NextResponse } from 'next/server' import { env, isTruthy } from '@/lib/env' +import { MAX_EXECUTION_DURATION } from '@/lib/execution/constants' import { executeInE2B } from '@/lib/execution/e2b' import { CodeLanguage, DEFAULT_CODE_LANGUAGE, isValidCodeLanguage } from '@/lib/execution/languages' import { createLogger } from '@/lib/logs/console/logger' @@ -8,7 +9,7 @@ import { validateProxyUrl } from '@/lib/security/input-validation' import { generateRequestId } from '@/lib/utils' export const dynamic = 'force-dynamic' export const runtime = 'nodejs' -export const maxDuration = 60 +export const maxDuration = MAX_EXECUTION_DURATION const logger = createLogger('FunctionExecuteAPI') @@ -649,10 +650,12 @@ export async function POST(req: NextRequest) { try { const body = await req.json() + const { DEFAULT_EXECUTION_TIMEOUT_MS } = await import('@/lib/execution/constants') + const { code, params = {}, - timeout = 5000, + timeout = DEFAULT_EXECUTION_TIMEOUT_MS, language = DEFAULT_CODE_LANGUAGE, useLocalVM = false, envVars = {}, diff --git a/apps/sim/executor/handlers/function/function-handler.test.ts b/apps/sim/executor/handlers/function/function-handler.test.ts index f1054743a2a..ad48e088051 100644 --- a/apps/sim/executor/handlers/function/function-handler.test.ts +++ b/apps/sim/executor/handlers/function/function-handler.test.ts @@ -1,4 +1,5 @@ import { beforeEach, describe, expect, it, type Mock, vi } from 'vitest' +import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/execution/constants' import { BlockType } from '@/executor/consts' import { FunctionBlockHandler } from '@/executor/handlers/function/function-handler' import type { ExecutionContext } from '@/executor/types' @@ -82,7 +83,7 @@ describe('FunctionBlockHandler', () => { workflowVariables: {}, blockData: {}, blockNameMapping: {}, - _context: { workflowId: mockContext.workflowId }, + _context: { workflowId: mockContext.workflowId, workspaceId: mockContext.workspaceId }, } const expectedOutput: any = { result: 'Success' } @@ -116,7 +117,7 @@ describe('FunctionBlockHandler', () => { workflowVariables: {}, blockData: {}, blockNameMapping: {}, - _context: { workflowId: mockContext.workflowId }, + _context: { workflowId: mockContext.workflowId, workspaceId: mockContext.workspaceId }, } const expectedOutput: any = { result: 'Success' } @@ -138,12 +139,12 @@ describe('FunctionBlockHandler', () => { code: inputs.code, language: 'javascript', useLocalVM: true, - timeout: 5000, // Default timeout + timeout: DEFAULT_EXECUTION_TIMEOUT_MS, envVars: {}, workflowVariables: {}, blockData: {}, blockNameMapping: {}, - _context: { workflowId: mockContext.workflowId }, + _context: { workflowId: mockContext.workflowId, workspaceId: mockContext.workspaceId }, } await handler.execute(mockBlock, inputs, mockContext) diff --git a/apps/sim/executor/handlers/function/function-handler.ts b/apps/sim/executor/handlers/function/function-handler.ts index dac9b958cfb..9d71759258b 100644 --- a/apps/sim/executor/handlers/function/function-handler.ts +++ b/apps/sim/executor/handlers/function/function-handler.ts @@ -1,3 +1,4 @@ +import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/execution/constants' import { DEFAULT_CODE_LANGUAGE } from '@/lib/execution/languages' import { createLogger } from '@/lib/logs/console/logger' import { BlockType } from '@/executor/consts' @@ -61,7 +62,7 @@ export class FunctionBlockHandler implements BlockHandler { code: codeContent, language: inputs.language || DEFAULT_CODE_LANGUAGE, useLocalVM: !inputs.remoteExecution, - timeout: inputs.timeout || 5000, + timeout: inputs.timeout || DEFAULT_EXECUTION_TIMEOUT_MS, envVars: context.environmentVariables || {}, workflowVariables: context.workflowVariables || {}, blockData: blockData, // Pass block data for variable resolution diff --git a/apps/sim/lib/execution/constants.ts b/apps/sim/lib/execution/constants.ts new file mode 100644 index 00000000000..4fcdab36505 --- /dev/null +++ b/apps/sim/lib/execution/constants.ts @@ -0,0 +1,10 @@ +/** + * Execution timeout constants + * + * These constants define the timeout values for code execution. + * - DEFAULT_EXECUTION_TIMEOUT_MS: The default timeout for executing user code (3 minutes) + * - MAX_EXECUTION_DURATION: The maximum duration for the API route (adds 30s buffer for overhead) + */ + +export const DEFAULT_EXECUTION_TIMEOUT_MS = 180000 // 3 minutes (180 seconds) +export const MAX_EXECUTION_DURATION = 210 // 3.5 minutes (210 seconds) - includes buffer for sandbox creation diff --git a/apps/sim/tools/function/execute.test.ts b/apps/sim/tools/function/execute.test.ts index ff9a45e4899..8b778a20682 100644 --- a/apps/sim/tools/function/execute.test.ts +++ b/apps/sim/tools/function/execute.test.ts @@ -7,6 +7,7 @@ * which runs JavaScript code in a secure sandbox. */ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/execution/constants' import { ToolTester } from '@/tools/__test-utils__/test-tools' import { functionExecuteTool } from '@/tools/function/execute' @@ -95,7 +96,7 @@ describe('Function Execute Tool', () => { expect(body).toEqual({ code: 'return 42', - timeout: 10000, + timeout: DEFAULT_EXECUTION_TIMEOUT_MS, envVars: {}, workflowVariables: {}, blockData: {}, diff --git a/apps/sim/tools/function/execute.ts b/apps/sim/tools/function/execute.ts index e8c9ca6a32f..c64291e4115 100644 --- a/apps/sim/tools/function/execute.ts +++ b/apps/sim/tools/function/execute.ts @@ -1,9 +1,8 @@ +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' -const DEFAULT_TIMEOUT = 10000 // 10 seconds - export const functionExecuteTool: ToolConfig = { id: 'function_execute', name: 'Function Execute', @@ -38,7 +37,7 @@ export const functionExecuteTool: ToolConfig