improvement(speed): refactor to skip proxy now that llm requests are done server-side, skip extra network hop (#325)

* improvement(speed): refactor to skip proxy now that llm requests are done server-side, skip extra network hop

* removed extraneous logs

* standardized logger names
This commit is contained in:
Waleed Latif
2025-05-04 14:07:17 -07:00
committed by GitHub
parent 4835782b4f
commit f4f5973f3c
34 changed files with 96 additions and 85 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from 'next/server'
import { auth } from '@/lib/auth'
import { createLogger } from '@/lib/logs/console-logger'
const logger = createLogger('ForgetPassword')
const logger = createLogger('ForgetPasswordAPI')
export async function POST(request: NextRequest) {
try {
+1 -1
View File
@@ -5,7 +5,7 @@ import { refreshOAuthToken } from '@/lib/oauth'
import { db } from '@/db'
import { account, workflow } from '@/db/schema'
const logger = createLogger('OAuthUtils')
const logger = createLogger('OAuthUtilsAPI')
/**
* Get the user ID based on either a session or a workflow ID
@@ -6,7 +6,7 @@ import { eq } from 'drizzle-orm'
import { createLogger } from '@/lib/logs/console-logger'
import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/utils'
const logger = createLogger('SubdomainValidate')
const logger = createLogger('SubdomainValidateAPI')
export async function GET(request: Request) {
// Check if the user is authenticated
+1 -1
View File
@@ -1,7 +1,7 @@
import { NextResponse } from 'next/server'
import { createLogger } from '@/lib/logs/console-logger'
const logger = createLogger('ProxyImage')
const logger = createLogger('ProxyImageAPI')
export async function GET(request: Request) {
try {
+1 -1
View File
@@ -1,7 +1,7 @@
import { NextResponse } from 'next/server'
import { createLogger } from '@/lib/logs/console-logger'
const logger = createLogger('ProxyTTS')
const logger = createLogger('ProxyTTSAPI')
export async function POST(request: Request) {
try {
+1 -1
View File
@@ -5,7 +5,7 @@ import { createLogger } from '@/lib/logs/console-logger'
import { db } from '@/db'
import { apiKey } from '@/db/schema'
const logger = createLogger('ApiKeyRoute')
const logger = createLogger('ApiKeyAPI')
// DELETE /api/user/api-keys/[id] - Delete an API key
export async function DELETE(
+1 -1
View File
@@ -7,7 +7,7 @@ import { generateApiKey } from '@/lib/utils'
import { db } from '@/db'
import { apiKey } from '@/db/schema'
const logger = createLogger('ApiKeysRoute')
const logger = createLogger('ApiKeysAPI')
// GET /api/user/api-keys - Get all API keys for the current user
export async function GET(request: NextRequest) {
+1 -1
View File
@@ -15,7 +15,7 @@
import { createLogger } from '@/lib/logs/console-logger'
import * as Sentry from '@sentry/nextjs'
const logger = createLogger('otel-instrumentation')
const logger = createLogger('OtelInstrumentation')
const DEFAULT_TELEMETRY_CONFIG = {
endpoint: process.env.TELEMETRY_ENDPOINT || 'https://telemetry.simstudio.ai/v1/traces',
+1 -1
View File
@@ -14,7 +14,7 @@ import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api'
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.ERROR)
const logger = createLogger('telemetry')
const logger = createLogger('Telemetry')
export type TelemetryEvent = {
name: string
+2 -2
View File
@@ -5,7 +5,7 @@ import { ProviderConfig, ProviderRequest, ProviderResponse, TimeSegment } from '
import { StreamingExecution } from '@/executor/types'
import { prepareToolsWithUsageControl, trackForcedToolUsage } from '../utils'
const logger = createLogger('Anthropic Provider')
const logger = createLogger('AnthropicProvider')
/**
* Helper to wrap Anthropic streaming (async iterable of SSE events) into a browser-friendly
@@ -449,7 +449,7 @@ ${fieldDescriptions}
...toolArgs,
...(request.workflowId ? { _context: { workflowId: request.workflowId } } : {}),
}
const result = await executeTool(toolName, mergedArgs)
const result = await executeTool(toolName, mergedArgs, true)
const toolCallEndTime = Date.now()
const toolCallDuration = toolCallEndTime - toolCallStartTime
+2 -2
View File
@@ -4,7 +4,7 @@ import { executeTool } from '@/tools'
import { ProviderConfig, ProviderRequest, ProviderResponse, TimeSegment } from '../types'
import { StreamingExecution } from '@/executor/types'
const logger = createLogger('Cerebras Provider')
const logger = createLogger('CerebrasProvider')
/**
* Helper to convert a Cerebras streaming response (async iterable) into a ReadableStream.
@@ -280,7 +280,7 @@ export const cerebrasProvider: ProviderConfig = {
...toolArgs,
...(request.workflowId ? { _context: { workflowId: request.workflowId } } : {}),
}
const result = await executeTool(toolName, mergedArgs)
const result = await executeTool(toolName, mergedArgs, true)
const toolCallEndTime = Date.now()
const toolCallDuration = toolCallEndTime - toolCallStartTime
+2 -2
View File
@@ -5,7 +5,7 @@ import { ProviderConfig, ProviderRequest, ProviderResponse, TimeSegment } from '
import { StreamingExecution } from '@/executor/types'
import { prepareToolsWithUsageControl, trackForcedToolUsage } from '../utils'
const logger = createLogger('Deepseek Provider')
const logger = createLogger('DeepseekProvider')
/**
* Helper function to convert a DeepSeek (OpenAI-compatible) stream to a ReadableStream
@@ -285,7 +285,7 @@ export const deepseekProvider: ProviderConfig = {
...toolArgs,
...(request.workflowId ? { _context: { workflowId: request.workflowId } } : {}),
}
const result = await executeTool(toolName, mergedArgs)
const result = await executeTool(toolName, mergedArgs, true)
const toolCallEndTime = Date.now()
const toolCallDuration = toolCallEndTime - toolCallStartTime
+2 -3
View File
@@ -3,7 +3,7 @@ import { executeTool } from '@/tools'
import { ProviderConfig, ProviderRequest, ProviderResponse, TimeSegment } from '../types'
import { StreamingExecution } from '@/executor/types'
const logger = createLogger('Google Provider')
const logger = createLogger('GoogleProvider')
/**
* Creates a ReadableStream from Google's Gemini stream response
@@ -371,8 +371,7 @@ export const googleProvider: ProviderConfig = {
hasRequiredParams: Object.keys(requiredToolCallParams).length > 0,
requiredParamKeys: Object.keys(requiredToolCallParams),
})
const result = await executeTool(toolName, mergedArgs)
const result = await executeTool(toolName, mergedArgs, true)
const toolCallEndTime = Date.now()
const toolCallDuration = toolCallEndTime - toolCallStartTime
+2 -2
View File
@@ -4,7 +4,7 @@ import { executeTool } from '@/tools'
import { ProviderConfig, ProviderRequest, ProviderResponse, TimeSegment } from '../types'
import { StreamingExecution } from '@/executor/types'
const logger = createLogger('Groq Provider')
const logger = createLogger('GroqProvider')
/**
* Helper to wrap Groq streaming into a browser-friendly ReadableStream
@@ -255,7 +255,7 @@ export const groqProvider: ProviderConfig = {
...toolArgs,
...(request.workflowId ? { _context: { workflowId: request.workflowId } } : {}),
}
const result = await executeTool(toolName, mergedArgs)
const result = await executeTool(toolName, mergedArgs, true)
const toolCallEndTime = Date.now()
const toolCallDuration = toolCallEndTime - toolCallStartTime
+2 -2
View File
@@ -5,7 +5,7 @@ import { executeTool } from '@/tools'
import { ProviderConfig, ProviderRequest, ProviderResponse, TimeSegment } from '../types'
import { ModelsObject } from './types'
const logger = createLogger('Ollama Provider')
const logger = createLogger('OllamaProvider')
const OLLAMA_HOST = process.env.OLLAMA_HOST || 'http://localhost:11434'
export const ollamaProvider: ProviderConfig = {
@@ -188,7 +188,7 @@ export const ollamaProvider: ProviderConfig = {
...toolArgs,
...(request.workflowId ? { _context: { workflowId: request.workflowId } } : {}),
}
const result = await executeTool(toolName, mergedArgs)
const result = await executeTool(toolName, mergedArgs, true)
const toolCallEndTime = Date.now()
const toolCallDuration = toolCallEndTime - toolCallStartTime
+3 -2
View File
@@ -5,7 +5,7 @@ import { ProviderConfig, ProviderRequest, ProviderResponse, TimeSegment } from '
import { prepareToolsWithUsageControl, trackForcedToolUsage } from '../utils'
import { StreamingExecution } from '@/executor/types'
const logger = createLogger('OpenAI Provider')
const logger = createLogger('OpenAIProvider')
/**
* Helper function to convert an OpenAI stream to a standard ReadableStream
@@ -351,7 +351,8 @@ export const openaiProvider: ProviderConfig = {
...toolArgs,
...(request.workflowId ? { _context: { workflowId: request.workflowId } } : {}),
}
const result = await executeTool(toolName, mergedArgs)
const result = await executeTool(toolName, mergedArgs, true)
const toolCallEndTime = Date.now()
const toolCallDuration = toolCallEndTime - toolCallStartTime
+2 -2
View File
@@ -5,7 +5,7 @@ import { ProviderConfig, ProviderRequest, ProviderResponse, TimeSegment } from '
import { StreamingExecution } from '@/executor/types'
import { prepareToolsWithUsageControl, trackForcedToolUsage } from '../utils'
const logger = createLogger('XAI Provider')
const logger = createLogger('XAIProvider')
/**
* Helper to wrap XAI (OpenAI-compatible) streaming into a browser-friendly
@@ -300,7 +300,7 @@ export const xAIProvider: ProviderConfig = {
...toolArgs,
...(request.workflowId ? { _context: { workflowId: request.workflowId } } : {}),
}
const result = await executeTool(toolName, mergedArgs)
const result = await executeTool(toolName, mergedArgs, true)
const toolCallEndTime = Date.now()
const toolCallDuration = toolCallEndTime - toolCallStartTime
+1 -1
View File
@@ -6,7 +6,7 @@ import { useWorkflowStore } from '../workflows/workflow/store'
import { CopilotMessage, CopilotStore } from './types'
import { calculateBlockPosition, getNextBlockNumber } from './utils'
const logger = createLogger('Copilot Store')
const logger = createLogger('CopilotStore')
export const useCopilotStore = create<CopilotStore>()(
devtools(
+1 -1
View File
@@ -6,7 +6,7 @@ import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
import { Variable, VariablesStore } from './types'
const logger = createLogger('Variables Store')
const logger = createLogger('VariablesStore')
const SAVE_DEBOUNCE_DELAY = 500 // 500ms debounce delay
// Map to store debounce timers for each workflow
+1 -1
View File
@@ -3,7 +3,7 @@ import { createLogger } from '@/lib/logs/console-logger'
import { API_ENDPOINTS } from '../../constants'
import { EnvironmentStore, EnvironmentVariable } from './types'
const logger = createLogger('Environment Store')
const logger = createLogger('EnvironmentStore')
export const useEnvironmentStore = create<EnvironmentStore>()((set, get) => ({
variables: {},
+1 -1
View File
@@ -1,6 +1,6 @@
import { createLogger } from '@/lib/logs/console-logger'
const logger = createLogger('Sync Core')
const logger = createLogger('SyncCore')
/**
* Core sync types and utilities for optimistic state synchronization
+1 -1
View File
@@ -5,7 +5,7 @@ import { SyncManager } from './sync'
import { isLocalStorageMode } from './sync-core'
import { fetchWorkflowsFromDB, workflowSync } from './workflows/sync'
const logger = createLogger('Sync Registry')
const logger = createLogger('SyncRegistry')
// Initialize managers lazily
let initialized = false
+1 -1
View File
@@ -8,7 +8,7 @@ import { useWorkflowRegistry } from './registry/store'
import { useSubBlockStore } from './subblock/store'
import { useWorkflowStore } from './workflow/store'
const logger = createLogger('Workflows Persistence')
const logger = createLogger('WorkflowsPersistence')
/**
* Save data to localStorage with error handling
+1 -1
View File
@@ -16,7 +16,7 @@ import { useWorkflowStore } from '../workflow/store'
import { WorkflowMetadata, WorkflowRegistry } from './types'
import { generateUniqueName, getNextWorkflowColor } from './utils'
const logger = createLogger('Workflow Registry')
const logger = createLogger('WorkflowRegistry')
// Storage key for active workspace
const ACTIVE_WORKSPACE_KEY = 'active-workspace-id'
+1 -1
View File
@@ -10,7 +10,7 @@ import { useSubBlockStore } from './subblock/store'
import { useWorkflowStore } from './workflow/store'
import { BlockState } from './workflow/types'
const logger = createLogger('Workflows Sync')
const logger = createLogger('WorkflowsSync')
// Add debounce utility
let syncDebounceTimer: NodeJS.Timeout | null = null
+1 -1
View File
@@ -2,7 +2,7 @@ import { createLogger } from '@/lib/logs/console-logger'
import { ToolConfig } from '../types'
import { PromptManagerParams, PromptManagerResponse } from './types'
const logger = createLogger('AutoblocksPromptManager')
const logger = createLogger('AutoblocksPromptManagerTool')
export const promptManagerTool: ToolConfig<PromptManagerParams, PromptManagerResponse> = {
id: 'autoblocks_prompt_manager',
+1 -1
View File
@@ -2,7 +2,7 @@ import { createLogger } from '@/lib/logs/console-logger'
import { ToolConfig } from '../types'
import { BrowserUseRunTaskParams, BrowserUseRunTaskResponse, BrowserUseTaskOutput } from './types'
const logger = createLogger('BrowserUseTools')
const logger = createLogger('BrowserUseTool')
export const runTaskTool: ToolConfig<BrowserUseRunTaskParams, BrowserUseRunTaskResponse> = {
id: 'browser_use_run_task',
+1 -1
View File
@@ -2,7 +2,7 @@ import { createLogger } from '@/lib/logs/console-logger'
import { ToolConfig } from '../types'
import { GoogleDocsCreateResponse, GoogleDocsToolParams } from './types'
const logger = createLogger('Google Docs Create Tool')
const logger = createLogger('GoogleDocsCreateTool')
export const createTool: ToolConfig<GoogleDocsToolParams, GoogleDocsCreateResponse> = {
id: 'google_docs_create',
+1 -1
View File
@@ -3,7 +3,7 @@ import { ToolConfig } from '../types'
import { GoogleDriveDownloadResponse } from './types'
import { GoogleDriveToolParams } from './types'
const logger = createLogger('Google Drive Export Tool')
const logger = createLogger('GoogleDriveExportTool')
export const exportTool: ToolConfig<
GoogleDriveToolParams & { mimeType?: string },
+1 -1
View File
@@ -2,7 +2,7 @@ import { HttpMethod, TableRow, ToolConfig } from '../types'
import { createLogger } from '@/lib/logs/console-logger'
import { RequestParams, RequestResponse } from './types'
const logger = createLogger('HTTP Request Tool')
const logger = createLogger('HTTPRequestTool')
// Function to get the appropriate referer based on environment
const getReferer = (): string => {
+54 -43
View File
@@ -39,6 +39,58 @@ export async function executeTool(
throw new Error(`Tool not found: ${toolId}`)
}
// If we have a credential parameter, fetch the access token
if (contextParams.credential) {
logger.info(`[executeTool] Credential found for ${toolId}, fetching access token.`);
try {
const baseUrl = process.env.NEXT_PUBLIC_APP_URL
if (!baseUrl) {
throw new Error('NEXT_PUBLIC_APP_URL environment variable is not set')
}
const isServerSide = typeof window === 'undefined'
// Prepare the token payload
const tokenPayload: OAuthTokenPayload = {
credentialId: contextParams.credential,
}
// Add workflowId if it exists in params or context (only server-side)
if (isServerSide) {
const workflowId = contextParams.workflowId || contextParams._context?.workflowId
if (workflowId) {
tokenPayload.workflowId = workflowId
logger.info(`[executeTool] Added workflowId ${workflowId} to token payload for ${toolId}`);
}
}
const tokenUrl = new URL('/api/auth/oauth/token', baseUrl).toString()
const response = await fetch(tokenUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(tokenPayload),
})
if (!response.ok) {
const errorText = await response.text()
logger.error('[executeTool] Token fetch failed:', response.status, errorText)
throw new Error(`Failed to fetch access token: ${response.status} ${errorText}`)
}
const data = await response.json()
contextParams.accessToken = data.accessToken
logger.info(`[executeTool] Successfully fetched access token for ${toolId}`);
// Clean up params we don't need to pass to the actual tool
delete contextParams.credential
if (contextParams.workflowId) delete contextParams.workflowId
} catch (error) {
logger.error('[executeTool] Error fetching access token:', { error })
// Re-throw the error to fail the tool execution if token fetching fails
throw new Error(`Failed to obtain credential for tool ${toolId}: ${error instanceof Error ? error.message : String(error)}`);
}
}
// For any tool with direct execution capability, try it first
if (tool.directExecution) {
try {
@@ -148,6 +200,7 @@ export async function executeTool(
}
// For external APIs, use the proxy
logger.info(`[executeTool] Using handleProxyRequest for toolId=${toolId}`);
const result = await handleProxyRequest(toolId, contextParams)
// Apply post-processing if available and not skipped
@@ -482,54 +535,12 @@ async function handleProxyRequest(
toolId: string,
params: Record<string, any>
): Promise<ToolResponse> {
logger.info(`[handleProxyRequest] Entry: toolId=${toolId}`);
const baseUrl = process.env.NEXT_PUBLIC_APP_URL
if (!baseUrl) {
throw new Error('NEXT_PUBLIC_APP_URL environment variable is not set')
}
// If we have a credential parameter, fetch the access token
if (params.credential) {
try {
const isServerSide = typeof window === 'undefined'
// Prepare the token payload
const tokenPayload: OAuthTokenPayload = {
credentialId: params.credential,
}
// Add workflowId if it exists in params or context
if (isServerSide) {
// Try to get workflowId from params or context
const workflowId = params.workflowId || params._context?.workflowId
if (workflowId) {
tokenPayload.workflowId = workflowId
}
}
const response = await fetch(`${baseUrl}/api/auth/oauth/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(tokenPayload),
})
if (!response.ok) {
const errorText = await response.text()
logger.error('Token fetch failed:', response.status, errorText)
throw new Error(`Failed to fetch access token: ${response.status} ${errorText}`)
}
const data = await response.json()
params.accessToken = data.accessToken
// Clean up params we don't need to pass to the actual tool
delete params.credential
if (params.workflowId) delete params.workflowId
} catch (error) {
logger.error('Error fetching access token:', { error })
throw error
}
}
const proxyUrl = new URL('/api/proxy', baseUrl).toString()
try {
const response = await fetch(proxyUrl, {
+1 -1
View File
@@ -2,7 +2,7 @@ import { createLogger } from '@/lib/logs/console-logger'
import { ToolConfig } from '../types'
import { MistralParserInput, MistralParserOutput } from './types'
const logger = createLogger('mistral-parser')
const logger = createLogger('MistralParserTool')
export const mistralParserTool: ToolConfig<MistralParserInput, MistralParserOutput> = {
id: 'mistral_parser',
+1 -1
View File
@@ -5,7 +5,7 @@ import { useEnvironmentStore } from '@/stores/settings/environment/store'
import { tools } from './registry'
import { useCustomToolsStore } from '@/stores/custom-tools/store'
const logger = createLogger('Tools Utils')
const logger = createLogger('ToolsUtils')
/**
* Transforms a table from the store format to a key-value object
+1 -1
View File
@@ -2,7 +2,7 @@ import { createLogger } from '@/lib/logs/console-logger'
import { ToolConfig } from '../types'
import { WhatsAppToolResponse } from './types'
const logger = createLogger('WhatsApp Send Message Tool')
const logger = createLogger('WhatsAppSendMessageTool')
export const sendMessageTool: ToolConfig<any, WhatsAppToolResponse> = {
id: 'whatsapp_send_message',