From eac163cfd06094bcfcbf15ca7d6d54ba03a762ee Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Tue, 3 Feb 2026 16:28:28 -0800 Subject: [PATCH] update more callsites --- apps/sim/app/api/tools/stt/route.ts | 4 ++- .../sim/app/api/tools/textract/parse/route.ts | 5 ++-- apps/sim/app/api/tools/tts/route.ts | 3 +- apps/sim/app/api/tools/video/route.ts | 28 +++++++++++-------- apps/sim/lib/core/idempotency/service.ts | 5 ++-- .../sim/lib/core/security/input-validation.ts | 3 +- 6 files changed, 29 insertions(+), 19 deletions(-) diff --git a/apps/sim/app/api/tools/stt/route.ts b/apps/sim/app/api/tools/stt/route.ts index 8a3ed3ef2..63116fe32 100644 --- a/apps/sim/app/api/tools/stt/route.ts +++ b/apps/sim/app/api/tools/stt/route.ts @@ -2,6 +2,7 @@ import { createLogger } from '@sim/logger' import { type NextRequest, NextResponse } from 'next/server' import { extractAudioFromVideo, isVideoFile } from '@/lib/audio/extractor' import { checkInternalAuth } from '@/lib/auth/hybrid' +import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/core/execution-limits' import { downloadFileFromStorage } from '@/lib/uploads/utils/file-utils.server' import type { UserFile } from '@/executor/types' import type { TranscriptSegment } from '@/tools/stt/types' @@ -568,7 +569,8 @@ async function transcribeWithAssemblyAI( let transcript: any let attempts = 0 - const maxAttempts = 60 // 5 minutes with 5-second intervals + const pollIntervalMs = 5000 + const maxAttempts = Math.ceil(DEFAULT_EXECUTION_TIMEOUT_MS / pollIntervalMs) while (attempts < maxAttempts) { const statusResponse = await fetch(`https://api.assemblyai.com/v2/transcript/${id}`, { diff --git a/apps/sim/app/api/tools/textract/parse/route.ts b/apps/sim/app/api/tools/textract/parse/route.ts index 86fa83512..39199beb3 100644 --- a/apps/sim/app/api/tools/textract/parse/route.ts +++ b/apps/sim/app/api/tools/textract/parse/route.ts @@ -3,6 +3,7 @@ import { createLogger } from '@sim/logger' import { type NextRequest, NextResponse } from 'next/server' import { z } from 'zod' import { checkInternalAuth } from '@/lib/auth/hybrid' +import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/core/execution-limits' import { validateAwsRegion, validateExternalUrl, @@ -205,8 +206,8 @@ async function pollForJobCompletion( useAnalyzeDocument: boolean, requestId: string ): Promise> { - const pollIntervalMs = 5000 // 5 seconds between polls - const maxPollTimeMs = 180000 // 3 minutes maximum polling time + const pollIntervalMs = 5000 + const maxPollTimeMs = DEFAULT_EXECUTION_TIMEOUT_MS const maxAttempts = Math.ceil(maxPollTimeMs / pollIntervalMs) const getTarget = useAnalyzeDocument diff --git a/apps/sim/app/api/tools/tts/route.ts b/apps/sim/app/api/tools/tts/route.ts index bc7bbe738..f8e106554 100644 --- a/apps/sim/app/api/tools/tts/route.ts +++ b/apps/sim/app/api/tools/tts/route.ts @@ -2,6 +2,7 @@ import { createLogger } from '@sim/logger' import type { NextRequest } from 'next/server' import { NextResponse } from 'next/server' import { checkInternalAuth } from '@/lib/auth/hybrid' +import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/core/execution-limits' import { validateAlphanumericId } from '@/lib/core/security/input-validation' import { getBaseUrl } from '@/lib/core/utils/urls' import { StorageService } from '@/lib/uploads' @@ -60,7 +61,7 @@ export async function POST(request: NextRequest) { text, model_id: modelId, }), - signal: AbortSignal.timeout(60000), + signal: AbortSignal.timeout(DEFAULT_EXECUTION_TIMEOUT_MS), }) if (!response.ok) { diff --git a/apps/sim/app/api/tools/video/route.ts b/apps/sim/app/api/tools/video/route.ts index 375042e93..7391acf58 100644 --- a/apps/sim/app/api/tools/video/route.ts +++ b/apps/sim/app/api/tools/video/route.ts @@ -1,6 +1,7 @@ import { createLogger } from '@sim/logger' import { type NextRequest, NextResponse } from 'next/server' import { checkInternalAuth } from '@/lib/auth/hybrid' +import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/core/execution-limits' import { downloadFileFromStorage } from '@/lib/uploads/utils/file-utils.server' import type { UserFile } from '@/executor/types' import type { VideoRequestBody } from '@/tools/video/types' @@ -326,11 +327,12 @@ async function generateWithRunway( logger.info(`[${requestId}] Runway task created: ${taskId}`) - const maxAttempts = 120 // 10 minutes with 5-second intervals + const pollIntervalMs = 5000 + const maxAttempts = Math.ceil(DEFAULT_EXECUTION_TIMEOUT_MS / pollIntervalMs) let attempts = 0 while (attempts < maxAttempts) { - await sleep(5000) // Poll every 5 seconds + await sleep(pollIntervalMs) const statusResponse = await fetch(`https://api.dev.runwayml.com/v1/tasks/${taskId}`, { headers: { @@ -429,11 +431,12 @@ async function generateWithVeo( logger.info(`[${requestId}] Veo operation created: ${operationName}`) - const maxAttempts = 60 // 5 minutes with 5-second intervals + const pollIntervalMs = 5000 + const maxAttempts = Math.ceil(DEFAULT_EXECUTION_TIMEOUT_MS / pollIntervalMs) let attempts = 0 while (attempts < maxAttempts) { - await sleep(5000) + await sleep(pollIntervalMs) const statusResponse = await fetch( `https://generativelanguage.googleapis.com/v1beta/${operationName}`, @@ -541,11 +544,12 @@ async function generateWithLuma( logger.info(`[${requestId}] Luma generation created: ${generationId}`) - const maxAttempts = 120 // 10 minutes + const pollIntervalMs = 5000 + const maxAttempts = Math.ceil(DEFAULT_EXECUTION_TIMEOUT_MS / pollIntervalMs) let attempts = 0 while (attempts < maxAttempts) { - await sleep(5000) + await sleep(pollIntervalMs) const statusResponse = await fetch( `https://api.lumalabs.ai/dream-machine/v1/generations/${generationId}`, @@ -658,14 +662,13 @@ async function generateWithMiniMax( logger.info(`[${requestId}] MiniMax task created: ${taskId}`) - // Poll for completion (6-10 minutes typical) - const maxAttempts = 120 // 10 minutes with 5-second intervals + const pollIntervalMs = 5000 + const maxAttempts = Math.ceil(DEFAULT_EXECUTION_TIMEOUT_MS / pollIntervalMs) let attempts = 0 while (attempts < maxAttempts) { - await sleep(5000) + await sleep(pollIntervalMs) - // Query task status const statusResponse = await fetch( `https://api.minimax.io/v1/query/video_generation?task_id=${taskId}`, { @@ -861,11 +864,12 @@ async function generateWithFalAI( // Get base model ID (without subpath) for status and result endpoints const baseModelId = getBaseModelId(falModelId) - const maxAttempts = 96 // 8 minutes with 5-second intervals + const pollIntervalMs = 5000 + const maxAttempts = Math.ceil(DEFAULT_EXECUTION_TIMEOUT_MS / pollIntervalMs) let attempts = 0 while (attempts < maxAttempts) { - await sleep(5000) + await sleep(pollIntervalMs) const statusResponse = await fetch( `https://queue.fal.run/${baseModelId}/requests/${requestIdFal}/status`, diff --git a/apps/sim/lib/core/idempotency/service.ts b/apps/sim/lib/core/idempotency/service.ts index 7a7239f9a..b8fae55c0 100644 --- a/apps/sim/lib/core/idempotency/service.ts +++ b/apps/sim/lib/core/idempotency/service.ts @@ -4,6 +4,7 @@ import { idempotencyKey } from '@sim/db/schema' import { createLogger } from '@sim/logger' import { eq } from 'drizzle-orm' import { getRedisClient } from '@/lib/core/config/redis' +import { getMaxExecutionTimeout } from '@/lib/core/execution-limits' import { getStorageMethod, type StorageMethod } from '@/lib/core/storage' import { extractProviderIdentifierFromBody } from '@/lib/webhooks/provider-utils' @@ -36,9 +37,9 @@ export interface AtomicClaimResult { storageMethod: StorageMethod } -const DEFAULT_TTL = 60 * 60 * 24 * 7 // 7 days +const DEFAULT_TTL = 60 * 60 * 24 * 7 const REDIS_KEY_PREFIX = 'idempotency:' -const MAX_WAIT_TIME_MS = 300000 // 5 minutes max wait +const MAX_WAIT_TIME_MS = getMaxExecutionTimeout() const POLL_INTERVAL_MS = 1000 /** diff --git a/apps/sim/lib/core/security/input-validation.ts b/apps/sim/lib/core/security/input-validation.ts index e27524b2c..c2bd0d9e4 100644 --- a/apps/sim/lib/core/security/input-validation.ts +++ b/apps/sim/lib/core/security/input-validation.ts @@ -4,6 +4,7 @@ import https from 'https' import type { LookupFunction } from 'net' import { createLogger } from '@sim/logger' import * as ipaddr from 'ipaddr.js' +import { DEFAULT_EXECUTION_TIMEOUT_MS } from '@/lib/core/execution-limits' const logger = createLogger('InputValidation') @@ -931,7 +932,7 @@ export async function secureFetchWithPinnedIP( method: options.method || 'GET', headers: sanitizedHeaders, agent, - timeout: options.timeout || 300000, // Default 5 minutes + timeout: options.timeout || DEFAULT_EXECUTION_TIMEOUT_MS, } const protocol = isHttps ? https : http