From decc138350f0da54266300acd9bb627538ec8ede Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Wed, 12 Mar 2025 01:35:04 -0700 Subject: [PATCH] feat(logger): added logger to remainder of files --- app/api/auth/oauth/token/route.ts | 2 +- app/api/chat/route.ts | 9 +- app/api/workflow/[id]/log/route.ts | 1 - app/api/workflow/[id]/status/route.ts | 1 - app/api/workflow/middleware.ts | 5 +- .../components/control-bar/control-bar.tsx | 5 +- app/w/[id]/components/error/index.tsx | 7 +- .../notifications/notifications.tsx | 12 +- .../components/sub-block/components/code.tsx | 6 +- .../sub-block/components/condition-input.tsx | 7 +- .../components/credential-selector.tsx | 7 +- .../sub-block/components/long-input.tsx | 6 +- .../sub-block/components/short-input.tsx | 5 +- .../custom-tool-modal/custom-tool-modal.tsx | 11 +- .../sub-block/components/webhook-config.tsx | 9 +- app/w/[id]/hooks/use-block-connections.ts | 5 +- app/w/[id]/hooks/use-workflow-execution.ts | 33 +----- app/w/[id]/workflow.tsx | 15 ++- .../components/help-form/help-form.tsx | 9 +- .../components/account/account.tsx | 5 +- .../components/credentials/credentials.tsx | 13 ++- .../components/control-bar/control-bar.tsx | 7 +- app/w/logs/logs.tsx | 8 +- blocks/blocks/evaluator.ts | 7 +- components/ui/file-selector.tsx | 13 ++- components/ui/oauth-required-modal.tsx | 7 +- components/ui/tag-dropdown.tsx | 11 +- components/ui/webhook-modal.tsx | 12 +- db/index.ts | 5 - executor/handlers.ts | 104 ++++-------------- executor/index.ts | 5 +- lib/auth.ts | 7 +- lib/logs/execution-logger.ts | 7 +- lib/oauth.ts | 7 +- lib/redis.ts | 19 ++-- lib/utils.ts | 5 +- lib/webcontainer.ts | 19 ++-- providers/anthropic/index.ts | 9 +- providers/cerebras/index.ts | 10 +- providers/deepseek/index.ts | 7 +- providers/google/index.ts | 7 +- providers/groq/index.ts | 7 +- providers/index.ts | 24 ++-- providers/openai/index.ts | 45 ++++---- providers/utils.ts | 41 +++++-- providers/xai/index.ts | 7 +- serializer/index.ts | 9 +- stores/chat/store.ts | 7 +- stores/index.ts | 29 ++--- stores/settings/environment/store.ts | 7 +- stores/sync-core.ts | 6 +- stores/sync-registry.ts | 7 +- stores/sync.ts | 9 +- stores/workflows/index.ts | 5 +- stores/workflows/persistence.ts | 9 +- stores/workflows/registry/store.ts | 10 +- stores/workflows/sync.ts | 31 +++--- tools/docs/create.ts | 13 +-- tools/drive/export.ts | 11 +- tools/index.ts | 25 +++-- tools/supabase/insert.ts | 7 -- tools/supabase/query.ts | 4 - tools/supabase/update.ts | 6 - tools/utils.ts | 5 +- tools/whatsapp/sendMessage.ts | 7 +- 65 files changed, 419 insertions(+), 361 deletions(-) diff --git a/app/api/auth/oauth/token/route.ts b/app/api/auth/oauth/token/route.ts index 7acf3741ad..b67128d47c 100644 --- a/app/api/auth/oauth/token/route.ts +++ b/app/api/auth/oauth/token/route.ts @@ -153,7 +153,7 @@ export async function GET(request: NextRequest) { return NextResponse.json({ accessToken: credential.accessToken }, { status: 200 }) } catch (error) { - console.error('Error getting OAuth token:', error) + logger.error('Error getting OAuth token:', { error }) return NextResponse.json({ error: 'Internal server error' }, { status: 500 }) } } diff --git a/app/api/chat/route.ts b/app/api/chat/route.ts index 9404f81878..4bbfa140f4 100644 --- a/app/api/chat/route.ts +++ b/app/api/chat/route.ts @@ -2,6 +2,9 @@ import { NextResponse } from 'next/server' import { OpenAI } from 'openai' import { ChatCompletionMessageParam } from 'openai/resources/chat/completions' import { z } from 'zod' +import { createLogger } from '@/lib/logs/console-logger' + +const logger = createLogger('ChatAPI') // Validation schemas const MessageSchema = z.object({ @@ -135,6 +138,8 @@ Only use the provided functions and respond naturally to the user's requests.` } export async function POST(request: Request) { + const requestId = crypto.randomUUID().slice(0, 8) + try { // Validate API key const apiKey = request.headers.get('X-OpenAI-Key') @@ -175,7 +180,7 @@ export async function POST(request: Request) { // Process tool calls if present if (message.tool_calls) { - console.log(message.tool_calls) + logger.debug(`[${requestId}] Tool calls:`, { toolCalls: message.tool_calls }) const actions = message.tool_calls.map((call) => ({ name: call.function.name, parameters: JSON.parse(call.function.arguments), @@ -194,7 +199,7 @@ export async function POST(request: Request) { "I'm not sure what changes to make to the workflow. Can you please provide more specific instructions?", }) } catch (error) { - console.error('Chat API error:', error) + logger.error(`[${requestId}] Chat API error:`, { error }) // Handle specific error types if (error instanceof z.ZodError) { diff --git a/app/api/workflow/[id]/log/route.ts b/app/api/workflow/[id]/log/route.ts index a85e2b1899..cbbde71b06 100644 --- a/app/api/workflow/[id]/log/route.ts +++ b/app/api/workflow/[id]/log/route.ts @@ -14,7 +14,6 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{ const { id } = await params try { - logger.debug(`[${requestId}] Persisting logs for workflow: ${id}`) const validation = await validateWorkflowAccess(request, id, false) if (validation.error) { logger.warn(`[${requestId}] Workflow access validation failed: ${validation.error.message}`) diff --git a/app/api/workflow/[id]/status/route.ts b/app/api/workflow/[id]/status/route.ts index 4f7b05caf4..c4de9e5a8d 100644 --- a/app/api/workflow/[id]/status/route.ts +++ b/app/api/workflow/[id]/status/route.ts @@ -10,7 +10,6 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{ try { const { id } = await params - logger.debug(`[${requestId}] Checking status for workflow: ${id}`) const validation = await validateWorkflowAccess(request, id, false) if (validation.error) { diff --git a/app/api/workflow/middleware.ts b/app/api/workflow/middleware.ts index d744f5bddd..74dcfeea47 100644 --- a/app/api/workflow/middleware.ts +++ b/app/api/workflow/middleware.ts @@ -1,6 +1,9 @@ import { NextRequest } from 'next/server' +import { createLogger } from '@/lib/logs/console-logger' import { getWorkflowById } from '@/lib/workflows' +const logger = createLogger('WorkflowMiddleware') + export interface ValidationResult { error?: { message: string; status: number } workflow?: any @@ -52,7 +55,7 @@ export async function validateWorkflowAccess( } return { workflow } } catch (error) { - console.error('Validation error:', error) + logger.error('Validation error:', { error }) return { error: { message: 'Internal server error', diff --git a/app/w/[id]/components/control-bar/control-bar.tsx b/app/w/[id]/components/control-bar/control-bar.tsx index f8b314e60a..52d691b788 100644 --- a/app/w/[id]/components/control-bar/control-bar.tsx +++ b/app/w/[id]/components/control-bar/control-bar.tsx @@ -23,6 +23,7 @@ import { DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' +import { createLogger } from '@/lib/logs/console-logger' import { cn } from '@/lib/utils' import { useNotificationStore } from '@/stores/notifications/store' import { useWorkflowRegistry } from '@/stores/workflows/registry/store' @@ -31,6 +32,8 @@ import { useWorkflowExecution } from '../../hooks/use-workflow-execution' import { HistoryDropdownItem } from './components/history-dropdown-item/history-dropdown-item' import { NotificationDropdownItem } from './components/notification-dropdown-item/notification-dropdown-item' +const logger = createLogger('ControlBar') + /** * Control bar for managing workflows - handles editing, deletion, deployment, * history, notifications and execution. @@ -106,7 +109,7 @@ export function ControlBar() { ) } } catch (error) { - console.error('Failed to check deployment status:', error) + logger.error('Failed to check deployment status:', { error }) } } checkStatus() diff --git a/app/w/[id]/components/error/index.tsx b/app/w/[id]/components/error/index.tsx index cd4b0eb5b0..27a4f14708 100644 --- a/app/w/[id]/components/error/index.tsx +++ b/app/w/[id]/components/error/index.tsx @@ -3,6 +3,9 @@ import { Component, ReactNode, useEffect } from 'react' import { BotIcon } from 'lucide-react' import { Card } from '@/components/ui/card' +import { createLogger } from '@/lib/logs/console-logger' + +const logger = createLogger('ErrorBoundary') // ======== Shared Error UI Component ======== interface ErrorUIProps { @@ -81,7 +84,7 @@ interface NextErrorProps { export function NextError({ error, reset }: NextErrorProps) { useEffect(() => { // Optionally log the error to an error reporting service - console.error('Workflow error:', error) + logger.error('Workflow error:', { error }) }, [error]) return @@ -96,7 +99,7 @@ export function NextGlobalError({ reset: () => void }) { useEffect(() => { - console.error('Global workspace error:', error) + logger.error('Global workspace error:', { error }) }, [error]) return ( diff --git a/app/w/[id]/components/notifications/notifications.tsx b/app/w/[id]/components/notifications/notifications.tsx index 5dec897bb4..1138b304a5 100644 --- a/app/w/[id]/components/notifications/notifications.tsx +++ b/app/w/[id]/components/notifications/notifications.tsx @@ -1,5 +1,5 @@ -import { useEffect, useRef, useState } from 'react' -import { ChevronDown, ChevronUp, Copy, Rocket, Terminal, X } from 'lucide-react' +import { useEffect, useState } from 'react' +import { Copy, Rocket, Terminal, X } from 'lucide-react' import { ErrorIcon } from '@/components/icons' import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert' import { @@ -13,15 +13,17 @@ import { AlertDialogTitle, } from '@/components/ui/alert-dialog' import { Button } from '@/components/ui/button' +import { createLogger } from '@/lib/logs/console-logger' import { cn } from '@/lib/utils' import { useNotificationStore } from '@/stores/notifications/store' -import { Notification, NotificationType } from '@/stores/notifications/types' +import { Notification } from '@/stores/notifications/types' import { useWorkflowStore } from '@/stores/workflows/workflow/store' +const logger = createLogger('Notifications') + // Constants const NOTIFICATION_TIMEOUT = 4000 const FADE_DURATION = 300 -const MAX_MESSAGE_HEIGHT = 300 // Maximum height in pixels before truncation // Icon mapping for notification types const NotificationIcon = { @@ -213,7 +215,7 @@ function NotificationAlert({ // Close the dialog setIsDeleteDialogOpen(false) } catch (error) { - console.error('Error deleting API deployment:', error) + logger.error('Error deleting API deployment:', { error }) } } diff --git a/app/w/[id]/components/workflow-block/components/sub-block/components/code.tsx b/app/w/[id]/components/workflow-block/components/sub-block/components/code.tsx index 7505c0a43d..91777a9042 100644 --- a/app/w/[id]/components/workflow-block/components/sub-block/components/code.tsx +++ b/app/w/[id]/components/workflow-block/components/sub-block/components/code.tsx @@ -4,12 +4,14 @@ import { highlight, languages } from 'prismjs' import 'prismjs/components/prism-javascript' import 'prismjs/themes/prism.css' import Editor from 'react-simple-code-editor' -import { Button } from '@/components/ui/button' import { EnvVarDropdown, checkEnvVarTrigger } from '@/components/ui/env-var-dropdown' import { TagDropdown, checkTagTrigger } from '@/components/ui/tag-dropdown' +import { createLogger } from '@/lib/logs/console-logger' import { cn } from '@/lib/utils' import { useSubBlockValue } from '../hooks/use-sub-block-value' +const logger = createLogger('Code') + interface CodeProps { blockId: string subBlockId: string @@ -148,7 +150,7 @@ export function Code({ } }, 0) } catch (error) { - console.error('Failed to parse drop data:', error) + logger.error('Failed to parse drop data:', { error }) } } diff --git a/app/w/[id]/components/workflow-block/components/sub-block/components/condition-input.tsx b/app/w/[id]/components/workflow-block/components/sub-block/components/condition-input.tsx index 110875afd2..4c9cb67ce7 100644 --- a/app/w/[id]/components/workflow-block/components/sub-block/components/condition-input.tsx +++ b/app/w/[id]/components/workflow-block/components/sub-block/components/condition-input.tsx @@ -10,10 +10,13 @@ import { Button } from '@/components/ui/button' import { EnvVarDropdown, checkEnvVarTrigger } from '@/components/ui/env-var-dropdown' import { TagDropdown, checkTagTrigger } from '@/components/ui/tag-dropdown' import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' +import { createLogger } from '@/lib/logs/console-logger' import { cn } from '@/lib/utils' import { useWorkflowStore } from '@/stores/workflows/workflow/store' import { useSubBlockValue } from '../hooks/use-sub-block-value' +const logger = createLogger('ConditionInput') + interface ConditionalBlock { id: string title: string @@ -145,7 +148,7 @@ export function ConditionInput({ blockId, subBlockId, isConnecting }: ConditionI }) ) } catch (error) { - console.error('Error updating block value:', error, { blockId, newValue }) + logger.error('Error updating block value:', { error, blockId, newValue }) } } @@ -280,7 +283,7 @@ export function ConditionInput({ blockId, subBlockId, isConnecting }: ConditionI } }, 0) } catch (error) { - console.error('Failed to parse drop data:', error) + logger.error('Failed to parse drop data:', { error }) } } diff --git a/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector.tsx b/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector.tsx index ec6617446e..7b03297ab0 100644 --- a/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector.tsx +++ b/app/w/[id]/components/workflow-block/components/sub-block/components/credential-selector.tsx @@ -14,6 +14,7 @@ import { import { OAuthRequiredModal } from '@/components/ui/oauth-required-modal' import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' import { client } from '@/lib/auth-client' +import { createLogger } from '@/lib/logs/console-logger' import { Credential, OAUTH_PROVIDERS, @@ -24,6 +25,8 @@ import { } from '@/lib/oauth' import { saveToStorage } from '@/stores/workflows/persistence' +const logger = createLogger('CredentialSelector') + interface CredentialSelectorProps { value: string onChange: (value: string) => void @@ -99,7 +102,7 @@ export function CredentialSelector({ } } } catch (error) { - console.error('Error fetching credentials:', error) + logger.error('Error fetching credentials:', { error }) } finally { setIsLoading(false) } @@ -162,7 +165,7 @@ export function CredentialSelector({ callbackURL: window.location.href, }) } catch (error) { - console.error('OAuth login error:', error) + logger.error('OAuth login error:', { error }) } } diff --git a/app/w/[id]/components/workflow-block/components/sub-block/components/long-input.tsx b/app/w/[id]/components/workflow-block/components/sub-block/components/long-input.tsx index 3fc32df75f..d50eeb7709 100644 --- a/app/w/[id]/components/workflow-block/components/sub-block/components/long-input.tsx +++ b/app/w/[id]/components/workflow-block/components/sub-block/components/long-input.tsx @@ -4,11 +4,13 @@ import { EnvVarDropdown, checkEnvVarTrigger } from '@/components/ui/env-var-drop import { formatDisplayText } from '@/components/ui/formatted-text' import { TagDropdown, checkTagTrigger } from '@/components/ui/tag-dropdown' import { Textarea } from '@/components/ui/textarea' +import { createLogger } from '@/lib/logs/console-logger' import { cn } from '@/lib/utils' -import { useWorkflowStore } from '@/stores/workflows/workflow/store' import { SubBlockConfig } from '@/blocks/types' import { useSubBlockValue } from '../hooks/use-sub-block-value' +const logger = createLogger('LongInput') + interface LongInputProps { placeholder?: string blockId: string @@ -105,7 +107,7 @@ export function LongInput({ }, 0) }) } catch (error) { - console.error('Failed to parse drop data:', error) + logger.error('Failed to parse drop data:', { error }) } } diff --git a/app/w/[id]/components/workflow-block/components/sub-block/components/short-input.tsx b/app/w/[id]/components/workflow-block/components/sub-block/components/short-input.tsx index 3f8064d4d2..2fda06d5af 100644 --- a/app/w/[id]/components/workflow-block/components/sub-block/components/short-input.tsx +++ b/app/w/[id]/components/workflow-block/components/sub-block/components/short-input.tsx @@ -4,10 +4,13 @@ import { EnvVarDropdown, checkEnvVarTrigger } from '@/components/ui/env-var-drop import { formatDisplayText } from '@/components/ui/formatted-text' import { Input } from '@/components/ui/input' import { TagDropdown, checkTagTrigger } from '@/components/ui/tag-dropdown' +import { createLogger } from '@/lib/logs/console-logger' import { cn } from '@/lib/utils' import { SubBlockConfig } from '@/blocks/types' import { useSubBlockValue } from '../hooks/use-sub-block-value' +const logger = createLogger('ShortInput') + interface ShortInputProps { placeholder?: string password?: boolean @@ -210,7 +213,7 @@ export function ShortInput({ }, 0) }) } catch (error) { - console.error('Failed to parse drop data:', error) + logger.error('Failed to parse drop data:', { error }) } } diff --git a/app/w/[id]/components/workflow-block/components/sub-block/components/tool-input/components/custom-tool-modal/custom-tool-modal.tsx b/app/w/[id]/components/workflow-block/components/sub-block/components/tool-input/components/custom-tool-modal/custom-tool-modal.tsx index 41a3d8abe3..607b2684a7 100644 --- a/app/w/[id]/components/workflow-block/components/sub-block/components/tool-input/components/custom-tool-modal/custom-tool-modal.tsx +++ b/app/w/[id]/components/workflow-block/components/sub-block/components/tool-input/components/custom-tool-modal/custom-tool-modal.tsx @@ -12,10 +12,13 @@ import { import { EnvVarDropdown, checkEnvVarTrigger } from '@/components/ui/env-var-dropdown' import { Label } from '@/components/ui/label' import { TagDropdown, checkTagTrigger } from '@/components/ui/tag-dropdown' +import { createLogger } from '@/lib/logs/console-logger' import { cn } from '@/lib/utils' import { useCustomToolsStore } from '@/stores/custom-tools/store' import { CodeEditor } from '../code-editor/code-editor' +const logger = createLogger('CustomToolModal') + interface CustomToolModalProps { open: boolean onOpenChange: (open: boolean) => void @@ -80,7 +83,7 @@ export function CustomToolModal({ setIsEditing(true) setToolId(initialValues.id) } catch (error) { - console.error('Error initializing form with initial values:', error) + logger.error('Error initializing form with initial values:', { error }) setSchemaError('Failed to load tool data. Please try again.') } } else if (open) { @@ -233,9 +236,7 @@ export function CustomToolModal({ onSave(customTool) handleClose() } catch (error) { - console.error('Error saving custom tool:', error) - setSchemaError('Failed to save custom tool. Please check your inputs and try again.') - console.error('Error saving custom tool:', error) + logger.error('Error saving custom tool:', { error }) setSchemaError('Failed to save custom tool. Please check your inputs and try again.') } } @@ -278,7 +279,7 @@ export function CustomToolModal({ setDropdownPosition({ top, left }) } } catch (error) { - console.error('Error calculating cursor position:', error) + logger.error('Error calculating cursor position:', { error }) } // Check if we should show the environment variables dropdown diff --git a/app/w/[id]/components/workflow-block/components/sub-block/components/webhook-config.tsx b/app/w/[id]/components/workflow-block/components/sub-block/components/webhook-config.tsx index 6523e23b8f..e8faf8721c 100644 --- a/app/w/[id]/components/workflow-block/components/sub-block/components/webhook-config.tsx +++ b/app/w/[id]/components/workflow-block/components/sub-block/components/webhook-config.tsx @@ -4,8 +4,11 @@ import { CheckCircle2, ExternalLink } from 'lucide-react' import { GithubIcon, StripeIcon, WhatsAppIcon } from '@/components/icons' import { Button } from '@/components/ui/button' import { WebhookModal } from '@/components/ui/webhook-modal' +import { createLogger } from '@/lib/logs/console-logger' import { useSubBlockValue } from '../hooks/use-sub-block-value' +const logger = createLogger('WebhookConfig') + export interface WebhookProvider { id: string name: string @@ -138,7 +141,7 @@ export function WebhookConfig({ blockId, subBlockId, isConnecting }: WebhookConf } } } catch (error) { - console.error('Error checking webhook:', error) + logger.error('Error checking webhook:', { error }) } } @@ -198,7 +201,7 @@ export function WebhookConfig({ blockId, subBlockId, isConnecting }: WebhookConf return true } catch (error: any) { - console.error('Error saving webhook:', error) + logger.error('Error saving webhook:', { error }) setError(error.message || 'Failed to save webhook configuration') return false } finally { @@ -228,7 +231,7 @@ export function WebhookConfig({ blockId, subBlockId, isConnecting }: WebhookConf return true } catch (error: any) { - console.error('Error deleting webhook:', error) + logger.error('Error deleting webhook:', { error }) setError(error.message || 'Failed to delete webhook') return false } finally { diff --git a/app/w/[id]/hooks/use-block-connections.ts b/app/w/[id]/hooks/use-block-connections.ts index 3a7b993f62..fbc154cf82 100644 --- a/app/w/[id]/hooks/use-block-connections.ts +++ b/app/w/[id]/hooks/use-block-connections.ts @@ -1,7 +1,10 @@ import { shallow } from 'zustand/shallow' +import { createLogger } from '@/lib/logs/console-logger' import { useSubBlockStore } from '@/stores/workflows/subblock/store' import { useWorkflowStore } from '@/stores/workflows/workflow/store' +const logger = createLogger('useBlockConnections') + interface Field { name: string type: string @@ -77,7 +80,7 @@ export function useBlockConnections(blockId: string) { ? JSON.parse(responseFormatValue) : responseFormatValue // Handle case where it's already an object } catch (e) { - console.error('Failed to parse response format:', e) + logger.error('Failed to parse response format:', { e }) responseFormat = undefined } diff --git a/app/w/[id]/hooks/use-workflow-execution.ts b/app/w/[id]/hooks/use-workflow-execution.ts index 39d2ddfbb1..6c03595027 100644 --- a/app/w/[id]/hooks/use-workflow-execution.ts +++ b/app/w/[id]/hooks/use-workflow-execution.ts @@ -1,5 +1,6 @@ import { useCallback, useState } from 'react' import { v4 as uuidv4 } from 'uuid' +import { createLogger } from '@/lib/logs/console-logger' import { useConsoleStore } from '@/stores/console/store' import { useExecutionStore } from '@/stores/execution/store' import { useNotificationStore } from '@/stores/notifications/store' @@ -12,6 +13,8 @@ import { Executor } from '@/executor' import { ExecutionResult } from '@/executor/types' import { Serializer } from '@/serializer' +const logger = createLogger('useWorkflowExecution') + export function useWorkflowExecution() { const { blocks, edges, loops } = useWorkflowStore() const { activeWorkflowId } = useWorkflowRegistry() @@ -61,7 +64,7 @@ export function useWorkflowExecution() { window.localStorage.setItem(logListKey, JSON.stringify(logList)) } catch (error) { - console.error('Error storing logs in localStorage:', error) + logger.error('Error storing logs in localStorage:', { error }) } return } @@ -80,7 +83,7 @@ export function useWorkflowExecution() { throw new Error('Failed to persist logs') } } catch (error) { - console.error('Error persisting logs:', error) + logger.error('Error persisting logs:', { error }) } } @@ -112,30 +115,6 @@ export function useWorkflowExecution() { {} as Record> ) - // Debug logging - console.group('Workflow Execution State') - console.log('Block Configurations:', blocks) - console.log( - 'SubBlock Store Values:', - useSubBlockStore.getState().workflowValues[activeWorkflowId] - ) - console.log('Merged Block States for Execution:', currentBlockStates) - - // Debug any responseFormat fields - const blockWithResponseFormat = Object.entries(currentBlockStates).find( - ([_id, state]) => state.responseFormat - ) - if (blockWithResponseFormat) { - console.log( - 'ResponseFormat found:', - blockWithResponseFormat[0], - typeof blockWithResponseFormat[1].responseFormat, - blockWithResponseFormat[1].responseFormat - ) - } - - console.groupEnd() - // Get environment variables const envVars = getAllVariables() const envVarValues = Object.entries(envVars).reduce( @@ -189,7 +168,7 @@ export function useWorkflowExecution() { // Persist logs after notification await persistLogs(blockLogs, executionId) } catch (error: any) { - console.error('Workflow Execution Error:', error) + logger.error('Workflow Execution Error:', { error }) const errorMessage = error instanceof Error ? error.message : 'Unknown error' diff --git a/app/w/[id]/workflow.tsx b/app/w/[id]/workflow.tsx index 72b840df84..c262e07064 100644 --- a/app/w/[id]/workflow.tsx +++ b/app/w/[id]/workflow.tsx @@ -7,13 +7,11 @@ import ReactFlow, { ConnectionLineType, EdgeTypes, NodeTypes, - Position, ReactFlowProvider, useReactFlow, } from 'reactflow' import 'reactflow/dist/style.css' -import { OAuthRequiredModal } from '@/components/ui/oauth-required-modal' -import { useNotificationStore } from '@/stores/notifications/store' +import { createLogger } from '@/lib/logs/console-logger' import { useGeneralStore } from '@/stores/settings/general/store' import { initializeSyncManagers, isSyncInitialized } from '@/stores/sync-registry' import { useWorkflowRegistry } from '@/stores/workflows/registry/store' @@ -28,6 +26,8 @@ import { LoopInput } from './components/workflow-loop/components/loop-input/loop import { LoopLabel } from './components/workflow-loop/components/loop-label/loop-label' import { createLoopNode, getRelativeLoopPosition } from './components/workflow-loop/workflow-loop' +const logger = createLogger('Workflow') + // Define custom node and edge types const nodeTypes: NodeTypes = { workflowBlock: WorkflowBlock, @@ -47,7 +47,6 @@ function WorkflowContent() { const { project } = useReactFlow() // Store access - const { addNotification } = useNotificationStore() const { workflows, setActiveWorkflow, createWorkflow } = useWorkflowRegistry() const { blocks, edges, loops, addBlock, updateBlockPosition, addEdge, removeEdge } = useWorkflowStore() @@ -114,13 +113,13 @@ function WorkflowContent() { // Add block nodes Object.entries(blocks).forEach(([blockId, block]) => { if (!block.type || !block.name) { - console.log('Skipping invalid block:', blockId, block) + logger.warn(`Skipping invalid block: ${blockId}`, { block }) return } const blockConfig = getBlock(block.type) if (!blockConfig) { - console.error(`No configuration found for block type: ${block.type}`) + logger.error(`No configuration found for block type: ${block.type}`, { block }) return } @@ -241,7 +240,7 @@ function WorkflowContent() { const blockConfig = getBlock(data.type) if (!blockConfig) { - console.error('Invalid block type:', data.type) + logger.error('Invalid block type:', { data }) return } @@ -268,7 +267,7 @@ function WorkflowContent() { } } } catch (err) { - console.error('Error dropping block:', err) + logger.error('Error dropping block:', { err }) } }, [project, blocks, addBlock, addEdge, findClosestOutput] diff --git a/app/w/components/sidebar/components/help-modal/components/help-form/help-form.tsx b/app/w/components/sidebar/components/help-modal/components/help-form/help-form.tsx index ccc14104bc..18f182d65f 100644 --- a/app/w/components/sidebar/components/help-modal/components/help-form/help-form.tsx +++ b/app/w/components/sidebar/components/help-modal/components/help-form/help-form.tsx @@ -19,6 +19,9 @@ import { SelectValue, } from '@/components/ui/select' import { Textarea } from '@/components/ui/textarea' +import { createLogger } from '@/lib/logs/console-logger' + +const logger = createLogger('HelpForm') // Define form schema const formSchema = z.object({ @@ -119,7 +122,7 @@ export function HelpForm({ onClose }: HelpFormProps) { lastModified: new Date().getTime(), }) } catch (error) { - console.warn('Image compression failed, using original file:', error) + logger.warn('Image compression failed, using original file:', { error }) return file } } @@ -167,7 +170,7 @@ export function HelpForm({ onClose }: HelpFormProps) { setImages((prev) => [...prev, ...newImages]) } } catch (error) { - console.error('Error processing images:', error) + logger.error('Error processing images:', { error }) setImageError('An error occurred while processing images. Please try again.') } finally { setIsProcessing(false) @@ -258,7 +261,7 @@ export function HelpForm({ onClose }: HelpFormProps) { images.forEach((image) => URL.revokeObjectURL(image.preview)) setImages([]) } catch (error) { - console.error('Error submitting help request:', error) + logger.error('Error submitting help request:', { error }) setSubmitStatus('error') setErrorMessage(error instanceof Error ? error.message : 'An unknown error occurred') } finally { diff --git a/app/w/components/sidebar/components/settings-modal/components/account/account.tsx b/app/w/components/sidebar/components/settings-modal/components/account/account.tsx index c2abe3a815..3e69ee4e16 100644 --- a/app/w/components/sidebar/components/settings-modal/components/account/account.tsx +++ b/app/w/components/sidebar/components/settings-modal/components/account/account.tsx @@ -12,9 +12,12 @@ import { DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' import { signOut, useSession } from '@/lib/auth-client' +import { createLogger } from '@/lib/logs/console-logger' import { cn } from '@/lib/utils' import { clearUserData } from '@/stores' +const logger = createLogger('Account') + interface AccountProps { onOpenChange: (open: boolean) => void } @@ -107,7 +110,7 @@ export function Account({ onOpenChange }: AccountProps) { // Still wait for the promise to resolve/reject to catch errors await signOutPromise } catch (error) { - console.error('Error signing out:', error) + logger.error('Error signing out:', { error }) // Still navigate even if there's an error router.push('/login?fromLogout=true') } finally { diff --git a/app/w/components/sidebar/components/settings-modal/components/credentials/credentials.tsx b/app/w/components/sidebar/components/settings-modal/components/credentials/credentials.tsx index 22aa3722c7..6e05bb45af 100644 --- a/app/w/components/sidebar/components/settings-modal/components/credentials/credentials.tsx +++ b/app/w/components/sidebar/components/settings-modal/components/credentials/credentials.tsx @@ -7,10 +7,13 @@ import { Button } from '@/components/ui/button' import { Card } from '@/components/ui/card' import { Skeleton } from '@/components/ui/skeleton' import { client, useSession } from '@/lib/auth-client' +import { createLogger } from '@/lib/logs/console-logger' import { OAUTH_PROVIDERS, OAuthServiceConfig } from '@/lib/oauth' import { cn } from '@/lib/utils' import { loadFromStorage, removeFromStorage, saveToStorage } from '@/stores/workflows/persistence' +const logger = createLogger('Credentials') + interface CredentialsProps { onOpenChange?: (open: boolean) => void } @@ -93,7 +96,7 @@ export function Credentials({ onOpenChange }: CredentialsProps) { setServices(serviceDefinitions) } } catch (error) { - console.error('Error fetching services:', error) + logger.error('Error fetching services:', { error }) // Use base definitions on error setServices(defineServices()) } finally { @@ -120,7 +123,7 @@ export function Credentials({ onOpenChange }: CredentialsProps) { // Clear the URL parameters router.replace('/w') } else if (error) { - console.error('OAuth error:', error) + logger.error('OAuth error:', { error }) router.replace('/w') } }, [searchParams, router, userId]) @@ -188,7 +191,7 @@ export function Credentials({ onOpenChange }: CredentialsProps) { callbackURL: window.location.href, }) } catch (error) { - console.error('OAuth login error:', error) + logger.error('OAuth login error:', { error }) setIsConnecting(null) } } @@ -224,10 +227,10 @@ export function Credentials({ onOpenChange }: CredentialsProps) { }) ) } else { - console.error('Error disconnecting service') + logger.error('Error disconnecting service') } } catch (error) { - console.error('Error disconnecting service:', error) + logger.error('Error disconnecting service:', { error }) } finally { setIsConnecting(null) } diff --git a/app/w/logs/components/control-bar/control-bar.tsx b/app/w/logs/components/control-bar/control-bar.tsx index 0fb1e398cf..9f07ddd52d 100644 --- a/app/w/logs/components/control-bar/control-bar.tsx +++ b/app/w/logs/components/control-bar/control-bar.tsx @@ -5,9 +5,12 @@ import { Loader2, Play, RefreshCw, Search, Square } from 'lucide-react' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' +import { createLogger } from '@/lib/logs/console-logger' import { useDebounce } from '../../hooks/use-debounce' import { useFilterStore } from '../../stores/store' -import { LogsResponse, WorkflowLog } from '../../stores/types' +import { LogsResponse } from '../../stores/types' + +const logger = createLogger('ControlBar') /** * Control bar for logs page - includes search functionality and refresh/live controls @@ -43,7 +46,7 @@ export function ControlBar() { const data: LogsResponse = await response.json() return data } catch (err) { - console.error('Failed to fetch logs:', err) + logger.error('Failed to fetch logs:', { err }) throw err } } diff --git a/app/w/logs/logs.tsx b/app/w/logs/logs.tsx index 979949882f..c627fa835f 100644 --- a/app/w/logs/logs.tsx +++ b/app/w/logs/logs.tsx @@ -1,8 +1,8 @@ 'use client' import { useEffect, useMemo, useState } from 'react' -import { format } from 'date-fns' import { AlertCircle, Info, Loader2 } from 'lucide-react' +import { createLogger } from '@/lib/logs/console-logger' import { ControlBar } from './components/control-bar/control-bar' import { Filters } from './components/filters/filters' import { Sidebar } from './components/sidebar/sidebar' @@ -10,6 +10,8 @@ import { useFilterStore } from './stores/store' import { LogsResponse, WorkflowLog } from './stores/types' import { formatDate } from './utils/format-date' +const logger = createLogger('Logs') + // Helper function to get level badge styling const getLevelBadgeStyles = (level: string) => { switch (level.toLowerCase()) { @@ -84,12 +86,12 @@ export default function Logs() { const data: LogsResponse = await response.json() // Log the response to console - console.log('Workflow logs response:', data) + logger.info('Workflow logs response:', data) setLogs(data.data) setError(null) } catch (err) { - console.error('Failed to fetch logs:', err) + logger.error('Failed to fetch logs:', { err }) setError(err instanceof Error ? err.message : 'An unknown error occurred') } finally { setLoading(false) diff --git a/blocks/blocks/evaluator.ts b/blocks/blocks/evaluator.ts index b8d644d6ee..40621fc6c0 100644 --- a/blocks/blocks/evaluator.ts +++ b/blocks/blocks/evaluator.ts @@ -1,9 +1,12 @@ import { ChartBarIcon } from '@/components/icons' +import { createLogger } from '@/lib/logs/console-logger' import { ProviderId } from '@/providers/types' import { MODEL_PROVIDERS } from '@/providers/utils' import { ToolResponse } from '@/tools/types' import { BlockConfig, ParamType } from '../types' +const logger = createLogger('EvaluatorBlock') + interface Metric { name: string description: string @@ -52,7 +55,7 @@ export const generateEvaluatorPrompt = (metrics: Metric[], content: string): str formattedContent = JSON.stringify(content, null, 2) } } catch (e) { - console.warn('Warning: Content may not be valid JSON, using as-is', e) + logger.warn('Warning: Content may not be valid JSON, using as-is', { e }) formattedContent = content } @@ -184,7 +187,7 @@ export const EvaluatorBlock: BlockConfig = { return JSON.stringify(result) } catch (e) { - console.error('Error in systemPrompt value function:', e) + logger.error('Error in systemPrompt value function:', { e }) // Return a minimal valid JSON as fallback return JSON.stringify({ systemPrompt: 'Evaluate the content and return a JSON with metric scores.', diff --git a/components/ui/file-selector.tsx b/components/ui/file-selector.tsx index 53f01871ac..a960cc1743 100644 --- a/components/ui/file-selector.tsx +++ b/components/ui/file-selector.tsx @@ -14,6 +14,7 @@ import { } from '@/components/ui/command' import { OAuthRequiredModal } from '@/components/ui/oauth-required-modal' import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' +import { createLogger } from '@/lib/logs/console-logger' import { Credential, OAUTH_PROVIDERS, @@ -25,6 +26,8 @@ import { } from '@/lib/oauth' import { saveToStorage } from '@/stores/workflows/persistence' +const logger = createLogger('FileSelector') + export interface FileInfo { id: string name: string @@ -117,7 +120,7 @@ export function FileSelector({ } } } catch (error) { - console.error('Error fetching credentials:', error) + logger.error('Error fetching credentials:', { error }) } finally { setIsLoading(false) } @@ -146,11 +149,11 @@ export function FileSelector({ return data.file } } else { - console.error('Error fetching file by ID:', await response.text()) + logger.error('Error fetching file by ID:', { error: await response.text() }) } return null } catch (error) { - console.error('Error fetching file by ID:', error) + logger.error('Error fetching file by ID:', { error }) return null } finally { setIsLoadingSelectedFile(false) @@ -198,11 +201,11 @@ export function FileSelector({ } } } else { - console.error('Error fetching files:', await response.text()) + logger.error('Error fetching files:', { error: await response.text() }) setFiles([]) } } catch (error) { - console.error('Error fetching files:', error) + logger.error('Error fetching files:', { error }) setFiles([]) } finally { setIsLoading(false) diff --git a/components/ui/oauth-required-modal.tsx b/components/ui/oauth-required-modal.tsx index eb0c46dc16..326d34096c 100644 --- a/components/ui/oauth-required-modal.tsx +++ b/components/ui/oauth-required-modal.tsx @@ -11,6 +11,7 @@ import { DialogTitle, } from '@/components/ui/dialog' import { client } from '@/lib/auth-client' +import { createLogger } from '@/lib/logs/console-logger' import { OAUTH_PROVIDERS, OAuthProvider, @@ -20,6 +21,8 @@ import { } from '@/lib/oauth' import { saveToStorage } from '@/stores/workflows/persistence' +const logger = createLogger('OAuthRequiredModal') + export interface OAuthRequiredModalProps { isOpen: boolean onClose: () => void @@ -107,7 +110,7 @@ export function OAuthRequiredModal({ }) window.dispatchEvent(event) } catch (error) { - console.error('Error redirecting to settings:', error) + logger.error('Error redirecting to settings:', { error }) } } @@ -131,7 +134,7 @@ export function OAuthRequiredModal({ callbackURL: window.location.href, }) } catch (error) { - console.error('Error initiating OAuth flow:', error) + logger.error('Error initiating OAuth flow:', { error }) } } diff --git a/components/ui/tag-dropdown.tsx b/components/ui/tag-dropdown.tsx index 05f63b32c3..744bb4704e 100644 --- a/components/ui/tag-dropdown.tsx +++ b/components/ui/tag-dropdown.tsx @@ -1,8 +1,11 @@ import React, { useEffect, useMemo, useState } from 'react' +import { createLogger } from '@/lib/logs/console-logger' import { cn } from '@/lib/utils' import { useSubBlockStore } from '@/stores/workflows/subblock/store' import { useWorkflowStore } from '@/stores/workflows/workflow/store' +const logger = createLogger('TagDropdown') + interface Field { name: string type: string @@ -127,7 +130,7 @@ export const TagDropdown: React.FC = ({ } } } catch (e) { - console.error('Error parsing metrics:', e) + logger.error('Error parsing metrics:', { e }) } } @@ -152,7 +155,7 @@ export const TagDropdown: React.FC = ({ } } } catch (e) { - console.error('Error parsing response format:', e) + logger.error('Error parsing response format:', { e }) } // Fall back to default outputs if no response format @@ -190,7 +193,7 @@ export const TagDropdown: React.FC = ({ } } } catch (e) { - console.error('Error parsing response format:', e) + logger.error('Error parsing response format:', { e }) } if (sourceBlock.type === 'evaluator') { @@ -204,7 +207,7 @@ export const TagDropdown: React.FC = ({ ) } } catch (e) { - console.error('Error parsing metrics:', e) + logger.error('Error parsing metrics:', { e }) return [] } } diff --git a/components/ui/webhook-modal.tsx b/components/ui/webhook-modal.tsx index 84b74e8e9a..f6b8ae7116 100644 --- a/components/ui/webhook-modal.tsx +++ b/components/ui/webhook-modal.tsx @@ -23,12 +23,13 @@ import { } from '@/components/ui/dialog' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' +import { createLogger } from '@/lib/logs/console-logger' import { ProviderConfig, WEBHOOK_PROVIDERS, - WebhookProvider, } from '@/app/w/[id]/components/workflow-block/components/sub-block/components/webhook-config' +const logger = createLogger('WebhookModal') interface WebhookModalProps { isOpen: boolean onClose: () => void @@ -101,7 +102,7 @@ export function WebhookModal({ } } } catch (error) { - console.error('Error fetching webhook config:', error) + logger.error('Error fetching webhook config:', { error }) } finally { setIsLoadingToken(false) } @@ -156,11 +157,10 @@ export function WebhookModal({ ? formattedPath.substring(1) : formattedPath - console.log('Saving webhook with path:', pathToSave) await onSave(pathToSave, providerConfig) } } catch (error) { - console.error('Error saving webhook:', error) + logger.error('Error saving webhook:', { error }) } finally { setIsSaving(false) } @@ -174,7 +174,7 @@ export function WebhookModal({ setShowDeleteConfirm(false) } } catch (error) { - console.error('Error deleting webhook:', error) + logger.error('Error deleting webhook:', { error }) } finally { setIsDeleting(false) } @@ -211,7 +211,7 @@ export function WebhookModal({ }) } } catch (error: any) { - console.error('Error testing webhook:', error) + logger.error('Error testing webhook:', { error }) setTestResult({ success: false, message: error.message || 'An error occurred while testing the webhook', diff --git a/db/index.ts b/db/index.ts index 7185d31984..4a4bf4026d 100644 --- a/db/index.ts +++ b/db/index.ts @@ -11,18 +11,13 @@ type DrizzleClient = ReturnType const createMockDb = (): DrizzleClient => { const mockHandler = { get: (target: any, prop: string) => { - // Return a function that logs and returns empty results if (typeof prop === 'string') { return (...args: any[]) => { - console.log(`[localStorage Mode] DB operation "${prop}" called with:`, args) - - // Create a chainable mock that always returns itself const chainableMock = new Proxy( {}, { get: (target, chainProp) => { if (chainProp === 'then') { - // Make it thenable to work with await return (resolve: Function) => resolve([]) } return chainableMock diff --git a/executor/handlers.ts b/executor/handlers.ts index 6696d0f042..0197e58ebd 100644 --- a/executor/handlers.ts +++ b/executor/handlers.ts @@ -1,3 +1,4 @@ +import { createLogger } from '@/lib/logs/console-logger' import { getAllBlocks } from '@/blocks' import { generateRouterPrompt } from '@/blocks/blocks/router' import { BlockOutput } from '@/blocks/types' @@ -9,6 +10,8 @@ import { executeTool, getTool } from '@/tools' import { PathTracker } from './path' import { ExecutionContext } from './types' +const logger = createLogger('Handlers') + /** * Interface for block handlers that execute specific block types. * Each handler is responsible for executing a particular type of block. @@ -60,14 +63,14 @@ async function executeCodeWithFallback( const result = await executeCode(code, params, timeout) if (!result.success) { - console.warn(`WebContainer API execution failed: ${result.error}`) + logger.warn(`WebContainer API execution failed: ${result.error}`) throw new Error(result.error || `WebContainer execution failed with no error message`) } return { success: true, output: result.output } } catch (error: any) { - console.warn('WebContainer execution failed, falling back to VM:', error) - console.error('WebContainer error details:', { + logger.warn('WebContainer execution failed, falling back to VM:', error) + logger.error('WebContainer error details:', { name: error.name, message: error.message, stack: error.stack, @@ -106,95 +109,40 @@ export class AgentBlockHandler implements BlockHandler { inputs: Record, context: ExecutionContext ): Promise { - console.log(`[AgentBlockHandler Debug] Executing agent block: ${block.id}`) - console.log(`[AgentBlockHandler Debug] Block inputs:`, JSON.stringify(inputs, null, 2)) + logger.info(`Executing agent block: ${block.id}`) // Check for null values and try to resolve from environment variables const nullInputs = Object.entries(inputs) .filter(([_, value]) => value === null) .map(([key]) => key) - if (nullInputs.length > 0) { - console.warn(`[AgentBlockHandler Debug] Null inputs detected:`, nullInputs) - - // Check if we can resolve API key from environment variables - if (nullInputs.includes('apiKey') && context.environmentVariables) { - console.log( - `[AgentBlockHandler Debug] Attempting to resolve API key from environment variables` - ) - console.log( - `[AgentBlockHandler Debug] Available env vars:`, - Object.keys(context.environmentVariables) - ) - - // Try different possible environment variable names for OpenAI API key - const possibleEnvVarNames = ['OPENAI_API_KEY', 'openai_api_key', 'OPENAI_KEY', 'openai_key'] - for (const envVar of possibleEnvVarNames) { - if (context.environmentVariables[envVar]) { - console.log( - `[AgentBlockHandler Debug] Found API key in environment variable: ${envVar}` - ) - inputs.apiKey = context.environmentVariables[envVar] - break - } - } - - // Check if we successfully resolved the API key - if (inputs.apiKey) { - console.log( - `[AgentBlockHandler Debug] Successfully resolved API key from environment variables` - ) - } else { - console.error( - `[AgentBlockHandler Debug] Failed to resolve API key from environment variables` - ) - } - } - } - // Parse response format if provided let responseFormat: any = undefined if (inputs.responseFormat) { // Handle empty string case - treat it as no response format if (inputs.responseFormat === '') { - console.log( - `[AgentBlockHandler Debug] Response format is an empty string, treating as undefined` - ) responseFormat = undefined } else { try { - console.log( - `[AgentBlockHandler Debug] Response format before parsing:`, - typeof inputs.responseFormat, - inputs.responseFormat - ) - responseFormat = typeof inputs.responseFormat === 'string' ? JSON.parse(inputs.responseFormat) : inputs.responseFormat - console.log(`[AgentBlockHandler Debug] Response format after parsing:`, responseFormat) - // Ensure the responseFormat is properly structured if (responseFormat && typeof responseFormat === 'object') { // If it's just a raw schema without the expected wrapper properties, // wrap it properly for the provider if (!responseFormat.schema && !responseFormat.name) { - console.log(`[AgentBlockHandler Debug] Wrapping raw schema in proper format`) responseFormat = { name: 'response_schema', schema: responseFormat, strict: true, } } - console.log( - `[AgentBlockHandler Debug] Final response format structure:`, - responseFormat - ) } } catch (error: any) { - console.error(`[AgentBlockHandler Error] Failed to parse response format:`, error) + logger.error(`Failed to parse response format:`, { error }) throw new Error(`Invalid response format: ${error.message}`) } } @@ -202,7 +150,7 @@ export class AgentBlockHandler implements BlockHandler { const model = inputs.model || 'gpt-4o' const providerId = getProviderFromModel(model) - console.log(`[AgentBlockHandler Debug] Using provider: ${providerId}, model: ${model}`) + logger.info(`Using provider: ${providerId}, model: ${model}`) // Format tools for provider API const formattedTools = Array.isArray(inputs.tools) @@ -243,7 +191,7 @@ export class AgentBlockHandler implements BlockHandler { return result.output } catch (error: any) { - console.error(`Error executing custom tool ${toolName}:`, error) + logger.error(`Error executing custom tool ${toolName}:`, error) throw new Error(`Error in ${toolName}: ${error.message}`) } }, @@ -290,36 +238,29 @@ export class AgentBlockHandler implements BlockHandler { responseFormat, } - console.log(`[AgentBlockHandler Debug] Provider request details:`, { + logger.info(`Provider request prepared`, { model: providerRequest.model, hasSystemPrompt: !!providerRequest.systemPrompt, hasContext: !!providerRequest.context, hasTools: !!providerRequest.tools, hasApiKey: !!providerRequest.apiKey, - apiKeyFirstChars: providerRequest.apiKey ? providerRequest.apiKey.substring(0, 4) : 'NONE', }) // Ensure context is properly formatted for the provider const response = await executeProviderRequest(providerId, providerRequest) - console.log(`[AgentBlockHandler Debug] Provider response:`, { - content: response.content, - contentType: typeof response.content, + logger.info(`Provider response received`, { contentLength: response.content ? response.content.length : 0, model: response.model, hasTokens: !!response.tokens, hasToolCalls: !!response.toolCalls, + toolCallsCount: response.toolCalls?.length || 0, }) // For structured responses, try to parse the content if (responseFormat) { try { - console.log( - `[AgentBlockHandler Debug] Attempting to parse response content as JSON:`, - response.content - ) const parsedContent = JSON.parse(response.content) - console.log(`[AgentBlockHandler Debug] Successfully parsed content:`, parsedContent) const result = { response: { @@ -338,11 +279,10 @@ export class AgentBlockHandler implements BlockHandler { }, } - console.log(`[AgentBlockHandler Debug] Result:`, result) return result } catch (error) { - console.error(`[AgentBlockHandler Error] Failed to parse response content:`, error) - console.log(`[AgentBlockHandler Debug] Falling back to standard response format`) + logger.error(`Failed to parse response content:`, { error }) + logger.info(`Falling back to standard response format`) // Fall back to standard response if parsing fails return { @@ -561,7 +501,7 @@ export class ConditionBlockHandler implements BlockHandler { } } } catch (error: any) { - console.error(`Failed to evaluate condition: ${error.message}`, { + logger.error(`Failed to evaluate condition: ${error.message}`, { condition, error, }) @@ -641,7 +581,7 @@ export class EvaluatorBlockHandler implements BlockHandler { processedContent = String(inputs.content || '') } } catch (e) { - console.error('Error processing content:', e) + logger.error('Error processing content:', e) processedContent = String(inputs.content || '') } @@ -732,12 +672,12 @@ export class EvaluatorBlockHandler implements BlockHandler { try { parsedContent = JSON.parse(jsonStr) } catch (parseError) { - console.error('Failed to parse extracted JSON:', parseError) + logger.error('Failed to parse extracted JSON:', parseError) throw new Error('Invalid JSON in response') } } catch (error) { - console.error('Error parsing evaluator response:', error) - console.error('Raw response content:', response.content) + logger.error('Error parsing evaluator response:', error) + logger.error('Raw response content:', response.content) // Fallback to empty object parsedContent = {} @@ -770,7 +710,7 @@ export class EvaluatorBlockHandler implements BlockHandler { if (matchingKey) { metricScores[metricName] = Number(parsedContent[matchingKey]) } else { - console.warn(`Metric "${metricName}" not found in LLM response`) + logger.warn(`Metric "${metricName}" not found in LLM response`) metricScores[metricName] = 0 } } @@ -782,7 +722,7 @@ export class EvaluatorBlockHandler implements BlockHandler { }) } } catch (e) { - console.error('Error extracting metric scores:', e) + logger.error('Error extracting metric scores:', e) } // Create result with metrics as direct fields for easy access diff --git a/executor/index.ts b/executor/index.ts index 1df766d01c..9f30d03415 100644 --- a/executor/index.ts +++ b/executor/index.ts @@ -1,3 +1,4 @@ +import { createLogger } from '@/lib/logs/console-logger' import { useConsoleStore } from '@/stores/console/store' import { useExecutionStore } from '@/stores/execution/store' import { BlockOutput } from '@/blocks/types' @@ -17,6 +18,8 @@ import { PathTracker } from './path' import { InputResolver } from './resolver' import { BlockLog, ExecutionContext, ExecutionResult, NormalizedBlockOutput } from './types' +const logger = createLogger('Executor') + /** * Core execution engine that runs workflow blocks in topological order. * @@ -111,7 +114,7 @@ export class Executor { logs: context.blockLogs, } } catch (error: any) { - console.error('Workflow execution failed:', error) + logger.error('Workflow execution failed:', { error }) return { success: false, diff --git a/lib/auth.ts b/lib/auth.ts index c7cf6b4e27..7594ff48f6 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -4,14 +4,17 @@ import { drizzleAdapter } from 'better-auth/adapters/drizzle' import { nextCookies } from 'better-auth/next-js' import { emailOTP, genericOAuth } from 'better-auth/plugins' import { Resend } from 'resend' +import { createLogger } from '@/lib/logs/console-logger' import { db } from '@/db' import * as schema from '@/db/schema' +const logger = createLogger('Auth') + // If there is no resend key, it might be a local dev environment // In that case, we don't want to send emails and just log them const resend = process.env.RESEND_API_KEY ? new Resend(process.env.RESEND_API_KEY) - : { emails: { send: async (...args: any[]) => console.log(args) } } + : { emails: { send: async (...args: any[]) => logger.info('Email sent:', args) } } export const auth = betterAuth({ database: drizzleAdapter(db, { @@ -93,7 +96,7 @@ export const auth = betterAuth({ throw new Error('Failed to send verification code') } } catch (error) { - console.error('Error sending verification code:', { + logger.error('Error sending verification code:', { error, email: data.email, otp: data.otp, diff --git a/lib/logs/execution-logger.ts b/lib/logs/execution-logger.ts index edc3c0d544..3823df6843 100644 --- a/lib/logs/execution-logger.ts +++ b/lib/logs/execution-logger.ts @@ -1,8 +1,11 @@ import { v4 as uuidv4 } from 'uuid' +import { createLogger } from '@/lib/logs/console-logger' import { db } from '@/db' import { workflowLogs } from '@/db/schema' import { ExecutionResult as ExecutorResult } from '@/executor/types' +const logger = createLogger('ExecutionLogger') + export interface LogEntry { id: string workflowId: string @@ -69,7 +72,7 @@ export async function persistExecutionLogs( createdAt: new Date(), }) } catch (error: any) { - console.error(`Error persisting execution logs: ${error.message}`, error) + logger.error(`Error persisting execution logs: ${error.message}`, { error }) } } @@ -100,7 +103,7 @@ export async function persistExecutionError( createdAt: new Date(), }) } catch (logError: any) { - console.error(`Error persisting execution error log: ${logError.message}`, logError) + logger.error(`Error persisting execution error log: ${logError.message}`, { logError }) } } diff --git a/lib/oauth.ts b/lib/oauth.ts index 70b6b01901..cfc11efd54 100644 --- a/lib/oauth.ts +++ b/lib/oauth.ts @@ -10,6 +10,9 @@ import { SupabaseIcon, xIcon, } from '@/components/icons' +import { createLogger } from '@/lib/logs/console-logger' + +const logger = createLogger('OAuth') // Define the base OAuth provider type export type OAuthProvider = 'google' | 'github' | 'x' | 'supabase' | string @@ -329,14 +332,14 @@ export async function refreshOAuthToken( if (!response.ok) { const errorText = await response.text() - console.error('Token refresh failed:', response.status, errorText) + logger.error('Token refresh failed:', { status: response.status, error: errorText }) throw new Error(`Failed to refresh token: ${response.status} ${errorText}`) } const data = await response.json() return data.access_token || null } catch (error) { - console.error('Error refreshing token:', error) + logger.error('Error refreshing token:', { error }) return null } } diff --git a/lib/redis.ts b/lib/redis.ts index 6da2f496e4..7d5e55b5f3 100644 --- a/lib/redis.ts +++ b/lib/redis.ts @@ -1,4 +1,7 @@ import Redis from 'ioredis' +import { createLogger } from '@/lib/logs/console-logger' + +const logger = createLogger('Redis') // Default to localhost if REDIS_URL is not provided const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379' @@ -34,7 +37,7 @@ export function getRedisClient(): Redis | null { // Retry strategy with exponential backoff retryStrategy: (times) => { if (times > 5) { - console.warn('Redis connection failed after 5 attempts, using fallback') + logger.warn('Redis connection failed after 5 attempts, using fallback') return null // Stop retrying } return Math.min(times * 200, 2000) // Exponential backoff @@ -43,19 +46,17 @@ export function getRedisClient(): Redis | null { // Handle connection events globalRedisClient.on('error', (err: any) => { - console.error('Redis connection error:', err) + logger.error('Redis connection error:', { err }) if (err.code === 'ECONNREFUSED' || err.code === 'ETIMEDOUT') { globalRedisClient = null } }) - globalRedisClient.on('connect', () => { - console.log('Connected to Redis') - }) + globalRedisClient.on('connect', () => {}) return globalRedisClient } catch (error) { - console.error('Failed to initialize Redis client:', error) + logger.error('Failed to initialize Redis client:', { error }) return null } } @@ -92,7 +93,7 @@ export async function hasProcessedMessage(messageId: string): Promise { return true } } catch (error) { - console.error('Error checking message ID:', error) + logger.error('Error checking message ID:', { error }) // Fallback to in-memory cache on error const cacheEntry = inMemoryCache.get(messageId) return !!cacheEntry && (!cacheEntry.expiry || cacheEntry.expiry > Date.now()) @@ -145,7 +146,7 @@ export async function markMessageAsProcessed( } } } catch (error) { - console.error('Error marking message as processed:', error) + logger.error('Error marking message as processed:', { error }) // Fallback to in-memory cache on error const expiry = expirySeconds ? Date.now() + expirySeconds * 1000 : null inMemoryCache.set(messageId, { value: '1', expiry }) @@ -161,7 +162,7 @@ export async function closeRedisConnection(): Promise { try { await globalRedisClient.quit() } catch (error) { - console.error('Error closing Redis connection:', error) + logger.error('Error closing Redis connection:', { error }) } finally { globalRedisClient = null } diff --git a/lib/utils.ts b/lib/utils.ts index 0f18b4cf76..8355b3317c 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -1,6 +1,9 @@ import { type ClassValue, clsx } from 'clsx' import { createCipheriv, createDecipheriv, createHash, randomBytes } from 'crypto' import { twMerge } from 'tailwind-merge' +import { createLogger } from '@/lib/logs/console-logger' + +const logger = createLogger('Utils') export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) @@ -64,7 +67,7 @@ export async function decryptSecret(encryptedValue: string): Promise<{ decrypted return { decrypted } } catch (error: any) { - console.error('Decryption error:', error.message) + logger.error('Decryption error:', { error: error.message }) throw error } } diff --git a/lib/webcontainer.ts b/lib/webcontainer.ts index 2be4a4e5c5..cbc78d5e95 100644 --- a/lib/webcontainer.ts +++ b/lib/webcontainer.ts @@ -1,5 +1,8 @@ import { WebContainer } from '@webcontainer/api' import { auth } from '@webcontainer/api' +import { createLogger } from '@/lib/logs/console-logger' + +const logger = createLogger('WebContainer') // Singleton instance of WebContainer let webcontainerInstance: WebContainer | null = null @@ -33,7 +36,7 @@ async function initializeAuth() { scope: '', }) } catch (error) { - console.error('Failed to initialize WebContainer auth:', error) + logger.error('Failed to initialize WebContainer auth:', { error }) throw error } } @@ -60,7 +63,7 @@ export async function getWebContainer(): Promise { // Check if cross-origin isolation is enabled if (!isCrossOriginIsolated()) { - console.warn('Cross-Origin Isolation is not enabled. WebContainers require COOP/COEP headers.') + logger.warn('Cross-Origin Isolation is not enabled. WebContainers require COOP/COEP headers.') throw new Error( 'WebContainers require cross-origin isolation. Please restart the server for changes to take effect.' ) @@ -86,7 +89,7 @@ export async function getWebContainer(): Promise { return webcontainerInstance } catch (error) { - console.error('WebContainer boot error:', error) + logger.error('WebContainer boot error:', { error }) isBooting = false bootPromise = null throw error @@ -262,7 +265,7 @@ export async function executeCode( // Don't resolve yet - wait for process to exit } catch (error) { - console.error('Failed to parse result', error) + logger.error('Failed to parse result', { error }) reject(error) } } @@ -286,7 +289,7 @@ export async function executeCode( process.stderr.pipeTo( new WritableStream({ write(data) { - console.error('WebContainer executeCode - Process error:', data) + logger.error('WebContainer executeCode - Process error:', { data }) stdout += `ERROR: ${data}\n` }, }) @@ -297,7 +300,7 @@ export async function executeCode( const timeoutPromise = new Promise((_, reject) => { setTimeout(() => { if (!processCompleted) { - console.error('WebContainer executeCode - Process timed out after', timeout, 'ms') + logger.error('WebContainer executeCode - Process timed out after', timeout, 'ms') reject(new Error(`Execution timed out after ${timeout}ms`)) } }, timeout) @@ -322,7 +325,7 @@ export async function executeCode( }, } } catch (error: any) { - console.error('WebContainer executeCode - Execution failed:', { + logger.error('WebContainer executeCode - Execution failed:', { error: error.message, name: error.name, stack: error.stack, @@ -334,7 +337,7 @@ export async function executeCode( try { await process.kill() } catch (killError) { - console.error('WebContainer executeCode - Failed to kill process:', killError) + logger.error('WebContainer executeCode - Failed to kill process:', { killError }) } } diff --git a/providers/anthropic/index.ts b/providers/anthropic/index.ts index fa55a0d094..4836a92abc 100644 --- a/providers/anthropic/index.ts +++ b/providers/anthropic/index.ts @@ -1,7 +1,10 @@ import Anthropic from '@anthropic-ai/sdk' +import { createLogger } from '@/lib/logs/console-logger' import { executeTool } from '@/tools' import { ProviderConfig, ProviderRequest, ProviderResponse } from '../types' +const logger = createLogger('Anthropic Provider') + export const anthropicProvider: ProviderConfig = { id: 'anthropic', name: 'Anthropic', @@ -264,7 +267,7 @@ ${fieldDescriptions} ], }) } catch (error) { - console.error('Error processing tool call:', error) + logger.error('Error processing tool call:', { error }) } } @@ -298,7 +301,7 @@ ${fieldDescriptions} iterationCount++ } } catch (error) { - console.error('Error in Anthropic request:', error) + logger.error('Error in Anthropic request:', { error }) throw error } @@ -310,7 +313,7 @@ ${fieldDescriptions} content = jsonMatch[0] } } catch (e) { - console.error('Error extracting JSON from response:', e) + logger.error('Error extracting JSON from response:', { error: e }) } } diff --git a/providers/cerebras/index.ts b/providers/cerebras/index.ts index 60422451c1..367d14e9fc 100644 --- a/providers/cerebras/index.ts +++ b/providers/cerebras/index.ts @@ -1,7 +1,10 @@ import { Cerebras } from '@cerebras/cerebras_cloud_sdk' +import { createLogger } from '@/lib/logs/console-logger' import { executeTool } from '@/tools' import { ProviderConfig, ProviderRequest, ProviderResponse } from '../types' +const logger = createLogger('Cerebras Provider') + export const cerebrasProvider: ProviderConfig = { id: 'cerebras', name: 'Cerebras', @@ -175,7 +178,7 @@ export const cerebrasProvider: ProviderConfig = { content: JSON.stringify(result.output), }) } catch (error) { - console.error('Error processing tool call:', error) + logger.error('Error processing tool call:', { error }) } } @@ -230,8 +233,7 @@ export const cerebrasProvider: ProviderConfig = { } } } catch (error) { - console.error('Error in Cerebras tool processing:', error) - // Don't throw here, return what we have so far + logger.error('Error in Cerebras tool processing:', { error }) } return { @@ -242,7 +244,7 @@ export const cerebrasProvider: ProviderConfig = { toolResults: toolResults.length > 0 ? toolResults : undefined, } } catch (error) { - console.error('Error in Cerebras request:', error) + logger.error('Error in Cerebras request:', { error }) throw error } }, diff --git a/providers/deepseek/index.ts b/providers/deepseek/index.ts index 366f19fab8..ecba4cc052 100644 --- a/providers/deepseek/index.ts +++ b/providers/deepseek/index.ts @@ -1,7 +1,10 @@ import OpenAI from 'openai' +import { createLogger } from '@/lib/logs/console-logger' import { executeTool } from '@/tools' import { ProviderConfig, ProviderRequest, ProviderResponse } from '../types' +const logger = createLogger('Deepseek Provider') + export const deepseekProvider: ProviderConfig = { id: 'deepseek', name: 'Deepseek', @@ -148,7 +151,7 @@ export const deepseekProvider: ProviderConfig = { content: JSON.stringify(result.output), }) } catch (error) { - console.error('Error processing tool call:', error) + logger.error('Error processing tool call:', { error }) } } @@ -179,7 +182,7 @@ export const deepseekProvider: ProviderConfig = { iterationCount++ } } catch (error) { - console.error('Error in Deepseek request:', error) + logger.error('Error in Deepseek request:', { error }) throw error } diff --git a/providers/google/index.ts b/providers/google/index.ts index e43ca6350f..6b59d4162e 100644 --- a/providers/google/index.ts +++ b/providers/google/index.ts @@ -1,7 +1,10 @@ import OpenAI from 'openai' +import { createLogger } from '@/lib/logs/console-logger' import { executeTool } from '@/tools' import { ProviderConfig, ProviderRequest, ProviderResponse } from '../types' +const logger = createLogger('Google Provider') + export const googleProvider: ProviderConfig = { id: 'google', name: 'Google', @@ -149,7 +152,7 @@ export const googleProvider: ProviderConfig = { content: toolResultContent, }) } catch (error) { - console.error('Error processing tool call:', error) + logger.error('Error processing tool call:', { error }) } } @@ -177,7 +180,7 @@ export const googleProvider: ProviderConfig = { iterationCount++ } } catch (error) { - console.error('Error in Google Gemini request:', error) + logger.error('Error in Google Gemini request:', { error }) throw error } diff --git a/providers/groq/index.ts b/providers/groq/index.ts index e5b1d1072f..9277cc77aa 100644 --- a/providers/groq/index.ts +++ b/providers/groq/index.ts @@ -1,7 +1,10 @@ import { Groq } from 'groq-sdk' +import { createLogger } from '@/lib/logs/console-logger' import { executeTool } from '@/tools' import { ProviderConfig, ProviderRequest, ProviderResponse } from '../types' +const logger = createLogger('Groq Provider') + export const groqProvider: ProviderConfig = { id: 'groq', name: 'Groq', @@ -146,7 +149,7 @@ export const groqProvider: ProviderConfig = { content: JSON.stringify(result.output), }) } catch (error) { - console.error('Error processing tool call:', error) + logger.error('Error processing tool call:', { error }) } } @@ -174,7 +177,7 @@ export const groqProvider: ProviderConfig = { iterationCount++ } } catch (error) { - console.error('Error in Groq request:', error) + logger.error('Error in Groq request:', { error }) throw error } diff --git a/providers/index.ts b/providers/index.ts index f4e30be9f5..9d08cc60ff 100644 --- a/providers/index.ts +++ b/providers/index.ts @@ -1,6 +1,9 @@ +import { createLogger } from '@/lib/logs/console-logger' import { supportsTemperature } from './model-capabilities' import { ProviderRequest, ProviderResponse } from './types' -import { generateStructuredOutputInstructions, getProvider, getProviderFromModel } from './utils' +import { generateStructuredOutputInstructions, getProvider } from './utils' + +const logger = createLogger('Providers') // Sanitize the request by removing parameters that aren't supported by the model function sanitizeRequest(request: ProviderRequest): ProviderRequest { @@ -19,8 +22,10 @@ export async function executeProviderRequest( providerId: string, request: ProviderRequest ): Promise { - console.log(`[Provider Debug] Executing request with provider: ${providerId}`) - console.log(`[Provider Debug] Request has responseFormat:`, !!request.responseFormat) + logger.info(`Executing request with provider: ${providerId}`, { + hasResponseFormat: !!request.responseFormat, + model: request.model, + }) const provider = getProvider(providerId) if (!provider) { @@ -39,24 +44,21 @@ export async function executeProviderRequest( typeof sanitizedRequest.responseFormat === 'string' && sanitizedRequest.responseFormat === '' ) { - console.log(`[Provider Debug] Response format is an empty string, ignoring it`) + logger.info(`Empty response format provided, ignoring it`) sanitizedRequest.responseFormat = undefined } else { - console.log(`[Provider Debug] Response format:`, sanitizedRequest.responseFormat) - + // Generate structured output instructions const structuredOutputInstructions = generateStructuredOutputInstructions( sanitizedRequest.responseFormat ) - console.log(`[Provider Debug] Generated instructions:`, structuredOutputInstructions) - // Only add additional instructions if they're not empty if (structuredOutputInstructions.trim()) { const originalPrompt = sanitizedRequest.systemPrompt || '' sanitizedRequest.systemPrompt = `${originalPrompt}\n\n${structuredOutputInstructions}`.trim() - console.log(`[Provider Debug] Updated system prompt with instructions`) + logger.info(`Added structured output instructions to system prompt`) } } } @@ -64,12 +66,12 @@ export async function executeProviderRequest( // Execute the request using the provider's implementation const response = await provider.executeRequest(sanitizedRequest) - console.log(`[Provider Debug] Provider response:`, { - contentType: typeof response.content, + logger.info(`Provider response received`, { contentLength: response.content ? response.content.length : 0, model: response.model, hasTokens: !!response.tokens, hasToolCalls: !!response.toolCalls, + toolCallsCount: response.toolCalls?.length || 0, }) return response diff --git a/providers/openai/index.ts b/providers/openai/index.ts index c0488525f5..1ce42b4e99 100644 --- a/providers/openai/index.ts +++ b/providers/openai/index.ts @@ -1,7 +1,10 @@ import OpenAI from 'openai' +import { createLogger } from '@/lib/logs/console-logger' import { executeTool } from '@/tools' import { ProviderConfig, ProviderRequest, ProviderResponse } from '../types' +const logger = createLogger('OpenAI Provider') + export const openaiProvider: ProviderConfig = { id: 'openai', name: 'OpenAI', @@ -11,20 +14,25 @@ export const openaiProvider: ProviderConfig = { defaultModel: 'gpt-4o', executeRequest: async (request: ProviderRequest): Promise => { - console.log('Full request:', request) + logger.info('Preparing OpenAI request', { + model: request.model || 'gpt-4o', + hasSystemPrompt: !!request.systemPrompt, + hasMessages: !!request.messages?.length, + hasTools: !!request.tools?.length, + toolCount: request.tools?.length || 0, + hasResponseFormat: !!request.responseFormat, + }) + if (!request.apiKey) { - console.error('OpenAI API key missing in request. Request details:', { + logger.error('OpenAI API key missing in request', { hasModel: !!request.model, hasSystemPrompt: !!request.systemPrompt, hasMessages: !!request.messages, hasTools: !!request.tools, - requestKeys: Object.keys(request), }) throw new Error('API key is required for OpenAI') } - console.log('OpenAI API key found in request (first 4 chars):', request.apiKey.substring(0, 4)) - const openai = new OpenAI({ apiKey: request.apiKey, dangerouslyAllowBrowser: true, @@ -78,15 +86,6 @@ export const openaiProvider: ProviderConfig = { // Add response format for structured output if specified if (request.responseFormat) { - // Log detailed information about the responseFormat - console.log(`[OpenAI Provider Debug] Response format details:`, { - type: typeof request.responseFormat, - isString: typeof request.responseFormat === 'string', - hasSchema: request.responseFormat.schema !== undefined, - hasName: request.responseFormat.name !== undefined, - value: JSON.stringify(request.responseFormat), - }) - // Use OpenAI's JSON schema format payload.response_format = { type: 'json_schema', @@ -97,17 +96,14 @@ export const openaiProvider: ProviderConfig = { }, } - // Log the final response_format being sent to OpenAI - console.log( - `[OpenAI Provider Debug] Final response_format:`, - JSON.stringify(payload.response_format) - ) + logger.info('Added JSON schema response format to request') } // Add tools if provided if (tools?.length) { payload.tools = tools payload.tool_choice = 'auto' + logger.info(`Configured ${tools.length} tools for OpenAI request`) } // Make the initial API request @@ -132,6 +128,10 @@ export const openaiProvider: ProviderConfig = { break } + logger.info( + `Processing ${toolCallsInResponse.length} tool calls (iteration ${iterationCount + 1}/${MAX_ITERATIONS})` + ) + // Process each tool call for (const toolCall of toolCallsInResponse) { try { @@ -176,7 +176,10 @@ export const openaiProvider: ProviderConfig = { content: JSON.stringify(result.output), }) } catch (error) { - console.error('Error processing tool call:', error) + logger.error('Error processing tool call:', { + error, + toolName: toolCall?.function?.name, + }) } } @@ -204,7 +207,7 @@ export const openaiProvider: ProviderConfig = { iterationCount++ } } catch (error) { - console.error('Error in OpenAI request:', error) + logger.error('Error in OpenAI request:', { error }) throw error } diff --git a/providers/utils.ts b/providers/utils.ts index 4425a8b96a..c4845e84d5 100644 --- a/providers/utils.ts +++ b/providers/utils.ts @@ -1,3 +1,4 @@ +import { createLogger } from '@/lib/logs/console-logger' import { useCustomToolsStore } from '@/stores/custom-tools/store' import { anthropicProvider } from './anthropic' import { cerebrasProvider } from './cerebras' @@ -8,6 +9,8 @@ import { openaiProvider } from './openai' import { ProviderConfig, ProviderId, ProviderToolConfig } from './types' import { xAIProvider } from './xai' +const logger = createLogger('ProviderUtils') + /** * Provider configurations with associated model names/patterns */ @@ -89,6 +92,7 @@ export function getProviderFromModel(model: string): ProviderId { } } + logger.warn(`No provider found for model: ${model}, defaulting to deepseek`) return 'deepseek' } @@ -161,6 +165,8 @@ export function generateStructuredOutputInstructions(responseFormat: any): strin }) .join('\n') + logger.info(`Generated structured output instructions for ${responseFormat.fields.length} fields`) + return ` Please provide your response in the following JSON format: { @@ -201,9 +207,13 @@ export function extractAndParseJSON(content: string): any { try { return JSON.parse(cleaned) } catch (innerError) { - console.error('Original content:', content) - console.error('Extracted JSON:', jsonStr) - console.error('Cleaned JSON:', cleaned) + logger.error('Failed to parse JSON response', { + contentLength: content.length, + extractedLength: jsonStr.length, + cleanedLength: cleaned.length, + error: innerError instanceof Error ? innerError.message : 'Unknown error', + }) + throw new Error( `Failed to parse JSON after cleanup: ${innerError instanceof Error ? innerError.message : 'Unknown error'}` ) @@ -241,6 +251,10 @@ export function getCustomTools(): ProviderToolConfig[] { // Get custom tools from the store const customTools = useCustomToolsStore.getState().getAllTools() + if (customTools.length > 0) { + logger.info(`Found ${customTools.length} custom tools`) + } + // Transform each custom tool into a provider tool config return customTools.map(transformCustomTool) } @@ -264,7 +278,10 @@ export function transformBlockTool( // Get the block definition const blockDef = getAllBlocks().find((b: any) => b.type === block.type) - if (!blockDef) return null + if (!blockDef) { + logger.warn(`Block definition not found for type: ${block.type}`) + return null + } // If the block has multiple operations, use the selected one or the first one let toolId: string | null = null @@ -279,7 +296,11 @@ export function transformBlockTool( operation: selectedOperation, }) } catch (error) { - console.error('Error selecting tool:', error) + logger.error('Error selecting tool for block', { + blockType: block.type, + operation: selectedOperation, + error, + }) return null } } else { @@ -291,11 +312,17 @@ export function transformBlockTool( toolId = blockDef.tools?.access?.[0] || null } - if (!toolId) return null + if (!toolId) { + logger.warn(`No tool ID found for block: ${block.type}`) + return null + } // Get the tool config const toolConfig = getTool(toolId) - if (!toolConfig) return null + if (!toolConfig) { + logger.warn(`Tool config not found for ID: ${toolId}`) + return null + } // Return formatted tool config return { diff --git a/providers/xai/index.ts b/providers/xai/index.ts index d9790f800d..2df6f8a824 100644 --- a/providers/xai/index.ts +++ b/providers/xai/index.ts @@ -1,7 +1,10 @@ import OpenAI from 'openai' +import { createLogger } from '@/lib/logs/console-logger' import { executeTool } from '@/tools' import { ProviderConfig, ProviderRequest, ProviderResponse } from '../types' +const logger = createLogger('XAI Provider') + export const xAIProvider: ProviderConfig = { id: 'xai', name: 'xAI', @@ -145,7 +148,7 @@ export const xAIProvider: ProviderConfig = { content: JSON.stringify(result.output), }) } catch (error) { - console.error('Error processing tool call:', error) + logger.error('Error processing tool call:', { error }) } } @@ -169,7 +172,7 @@ export const xAIProvider: ProviderConfig = { iterationCount++ } } catch (error) { - console.error('Error in xAI request:', error) + logger.error('Error in xAI request:', { error }) throw error } diff --git a/serializer/index.ts b/serializer/index.ts index b52e6204d0..337134dde9 100644 --- a/serializer/index.ts +++ b/serializer/index.ts @@ -1,7 +1,10 @@ import { Edge } from 'reactflow' -import { BlockState, Loop, SubBlockState } from '@/stores/workflows/workflow/types' +import { createLogger } from '@/lib/logs/console-logger' +import { BlockState, Loop } from '@/stores/workflows/workflow/types' import { getBlock } from '@/blocks' -import { SerializedBlock, SerializedConnection, SerializedWorkflow } from './types' +import { SerializedBlock, SerializedWorkflow } from './types' + +const logger = createLogger('Serializer') export class Serializer { serializeWorkflow( @@ -48,7 +51,7 @@ export class Serializer { : blockConfig.tools.access[0] } } catch (error) { - console.error('Error processing tools in agent block:', error) + logger.error('Error processing tools in agent block:', { error }) // Default to the first tool if we can't process tools toolId = blockConfig.tools.access[0] } diff --git a/stores/chat/store.ts b/stores/chat/store.ts index 632938f965..edc28c95f9 100644 --- a/stores/chat/store.ts +++ b/stores/chat/store.ts @@ -1,10 +1,13 @@ import { create } from 'zustand' import { devtools } from 'zustand/middleware' +import { createLogger } from '@/lib/logs/console-logger' import { useEnvironmentStore } from '../settings/environment/store' import { useWorkflowStore } from '../workflows/workflow/store' import { ChatMessage, ChatStore } from './types' import { calculateBlockPosition, getNextBlockNumber } from './utils' +const logger = createLogger('Chat Store') + export const useChatStore = create()( devtools( (set, get) => ({ @@ -71,8 +74,6 @@ export const useChatStore = create()( const data = await response.json() - console.log('OPENAI RESPONSE', data) - // Handle any actions returned from the API if (data.actions) { // Process all block additions first to properly calculate positions @@ -135,7 +136,7 @@ export const useChatStore = create()( })) } } catch (error) { - console.error('Chat error:', error) + logger.error('Chat error:', { error }) set({ error: error instanceof Error ? error.message : 'Unknown error' }) } finally { set({ isProcessing: false }) diff --git a/stores/index.ts b/stores/index.ts index 137fd27c44..ac4aaebeb2 100644 --- a/stores/index.ts +++ b/stores/index.ts @@ -1,4 +1,5 @@ import { useEffect } from 'react' +import { createLogger } from '@/lib/logs/console-logger' import { useChatStore } from './chat/store' import { useConsoleStore } from './console/store' import { useCustomToolsStore } from './custom-tools/store' @@ -17,6 +18,8 @@ import { useWorkflowRegistry } from './workflows/registry/store' import { useSubBlockStore } from './workflows/subblock/store' import { useWorkflowStore } from './workflows/workflow/store' +const logger = createLogger('Stores') + // Track initialization state let isInitializing = false @@ -47,7 +50,7 @@ async function initializeApplication(): Promise { // No workflows loaded from DB, try localStorage as fallback const workflows = loadRegistry() if (workflows && Object.keys(workflows).length > 0) { - console.log('Loading workflows from localStorage as fallback') + logger.info('Loading workflows from localStorage as fallback') useWorkflowRegistry.setState({ workflows }) const activeWorkflowId = useWorkflowRegistry.getState().activeWorkflowId @@ -56,13 +59,13 @@ async function initializeApplication(): Promise { } } } else { - console.log('Using workflows loaded from DB, ignoring localStorage') + logger.info('Using workflows loaded from DB, ignoring localStorage') } // 2. Register cleanup window.addEventListener('beforeunload', handleBeforeUnload) } catch (error) { - console.error('Error during application initialization:', error) + logger.error('Error during application initialization:', { error }) } finally { isInitializing = false } @@ -72,7 +75,7 @@ function initializeWorkflowState(workflowId: string): void { // Load the specific workflow state from localStorage const workflowState = loadWorkflowState(workflowId) if (!workflowState) { - console.warn(`No saved state found for workflow ${workflowId}`) + logger.warn(`No saved state found for workflow ${workflowId}`) return } @@ -94,7 +97,7 @@ function initializeWorkflowState(workflowId: string): void { useSubBlockStore.getState().initializeFromWorkflow(workflowId, workflowState.blocks) } - console.log(`Initialized workflow state for ${workflowId}`) + logger.info(`Initialized workflow state for ${workflowId}`) } /** @@ -167,9 +170,9 @@ export async function clearUserData(): Promise { const keysToRemove = Object.keys(localStorage).filter((key) => !keysToKeep.includes(key)) keysToRemove.forEach((key) => localStorage.removeItem(key)) - console.log('User data cleared successfully') + logger.info('User data cleared successfully') } catch (error) { - console.error('Error clearing user data:', error) + logger.error('Error clearing user data:', { error }) } } @@ -247,14 +250,6 @@ export const logAllStores = () => { subBlock: useSubBlockStore.getState(), } - console.group('Application State') - Object.entries(state).forEach(([storeName, storeState]) => { - console.group(storeName) - console.log(storeState) - console.groupEnd() - }) - console.groupEnd() - return state } @@ -275,8 +270,8 @@ export async function reinitializeAfterLogin(): Promise { // Reinitialize the application await initializeApplication() - console.log('Application reinitialized after login') + logger.info('Application reinitialized after login') } catch (error) { - console.error('Error reinitializing application:', error) + logger.error('Error reinitializing application:', { error }) } } diff --git a/stores/settings/environment/store.ts b/stores/settings/environment/store.ts index dc57e121a7..974686b445 100644 --- a/stores/settings/environment/store.ts +++ b/stores/settings/environment/store.ts @@ -1,7 +1,10 @@ import { create } from 'zustand' +import { createLogger } from '@/lib/logs/console-logger' import { API_ENDPOINTS } from '../../constants' import { EnvironmentStore, EnvironmentVariable } from './types' +const logger = createLogger('Environment Store') + export const useEnvironmentStore = create()((set, get) => ({ variables: {}, isLoading: false, @@ -32,7 +35,7 @@ export const useEnvironmentStore = create()((set, get) => ({ }) } } catch (error) { - console.error('Error loading environment variables:', error) + logger.error('Error loading environment variables:', { error }) set({ error: error instanceof Error ? error.message : 'Unknown error', isLoading: false, @@ -80,7 +83,7 @@ export const useEnvironmentStore = create()((set, get) => ({ set({ isLoading: false }) } catch (error) { - console.error('Error saving environment variables:', error) + logger.error('Error saving environment variables:', { error }) set({ error: error instanceof Error ? error.message : 'Unknown error', isLoading: false, diff --git a/stores/sync-core.ts b/stores/sync-core.ts index 2ca6ce0641..93c839ee57 100644 --- a/stores/sync-core.ts +++ b/stores/sync-core.ts @@ -1,3 +1,7 @@ +import { createLogger } from '@/lib/logs/console-logger' + +const logger = createLogger('Sync Core') + /** * Core sync types and utilities for optimistic state synchronization */ @@ -73,7 +77,7 @@ export async function performSync(config: SyncConfig): Promise { if (config.onSyncError) { config.onSyncError(error) } - console.error(`Sync error: ${error}`) + logger.error(`Sync error: ${error}`) return false } } diff --git a/stores/sync-registry.ts b/stores/sync-registry.ts index 294ff77341..82a481b59b 100644 --- a/stores/sync-registry.ts +++ b/stores/sync-registry.ts @@ -1,9 +1,12 @@ 'use client' +import { createLogger } from '@/lib/logs/console-logger' import { SyncManager } from './sync' import { isLocalStorageMode } from './sync-core' import { fetchWorkflowsFromDB, workflowSync } from './workflows/sync' +const logger = createLogger('Sync Registry') + // Initialize managers lazily let initialized = false let initializing = false @@ -42,13 +45,13 @@ export async function initializeSyncManagers(): Promise { // Remove environment variables fetch await fetchWorkflowsFromDB() } catch (error) { - console.error('Error fetching data from DB:', error) + logger.error('Error fetching data from DB:', { error }) } initialized = true return true } catch (error) { - console.error('Error initializing sync managers:', error) + logger.error('Error initializing sync managers:', { error }) return false } finally { initializing = false diff --git a/stores/sync.ts b/stores/sync.ts index 3cfb41d5eb..790b0a6987 100644 --- a/stores/sync.ts +++ b/stores/sync.ts @@ -1,6 +1,7 @@ 'use client' import { useEffect } from 'react' +import { createLogger } from '@/lib/logs/console-logger' import { SYNC_INTERVALS } from './constants' import { DEFAULT_SYNC_CONFIG, @@ -10,6 +11,8 @@ import { performSync, } from './sync-core' +const logger = createLogger('Sync') + // Client-side sync manager with lifecycle and registry management export interface SyncManager extends SyncOperations { id: string @@ -33,7 +36,7 @@ export function createSyncManager(config: SyncConfig): SyncManager { // Optimistic sync - fire and forget const sync = (): void => { performSync(fullConfig).catch((err) => { - console.error('Sync failed:', err) + logger.error('Sync failed:', { err }) }) } @@ -146,7 +149,7 @@ export function createSingletonSyncManager( return { id: key, config: configFactory(), - sync: () => console.log(`[LocalStorage Mode] Skipping sync for ${key}`), + sync: () => logger.info(`[LocalStorage Mode] Skipping sync for ${key}`), startIntervalSync: () => {}, stopIntervalSync: () => {}, dispose: () => {}, @@ -168,7 +171,7 @@ export function createSingletonSyncManager( config, sync: () => { performSync(config).catch((err) => { - console.error(`Sync failed for ${key}:`, err) + logger.error(`Sync failed for ${key}:`, { err }) }) }, startIntervalSync: () => { diff --git a/stores/workflows/index.ts b/stores/workflows/index.ts index bc6bf26c7c..d8d6e95112 100644 --- a/stores/workflows/index.ts +++ b/stores/workflows/index.ts @@ -1,3 +1,4 @@ +import { createLogger } from '@/lib/logs/console-logger' import { loadWorkflowState } from './persistence' import { useWorkflowRegistry } from './registry/store' import { useSubBlockStore } from './subblock/store' @@ -5,6 +6,8 @@ import { mergeSubblockState } from './utils' import { useWorkflowStore } from './workflow/store' import { BlockState, WorkflowState } from './workflow/types' +const logger = createLogger('Workflows') + // Get a specific block with its subblock values merged in export function getBlockWithValues(blockId: string): BlockState | null { const workflowState = useWorkflowStore.getState() @@ -42,7 +45,7 @@ export function getAllWorkflowsWithValues() { const savedState = loadWorkflowState(id) if (!savedState) { // Skip workflows with no saved state - console.warn(`No saved state found for workflow ${id}`) + logger.warn(`No saved state found for workflow ${id}`) continue } workflowState = savedState diff --git a/stores/workflows/persistence.ts b/stores/workflows/persistence.ts index f022ec9f28..bae15c20a3 100644 --- a/stores/workflows/persistence.ts +++ b/stores/workflows/persistence.ts @@ -2,11 +2,14 @@ * Centralized persistence layer for workflow stores * Handles localStorage interactions and synchronization */ +import { createLogger } from '@/lib/logs/console-logger' import { STORAGE_KEYS } from '../constants' import { useWorkflowRegistry } from './registry/store' import { useSubBlockStore } from './subblock/store' import { useWorkflowStore } from './workflow/store' +const logger = createLogger('Workflows Persistence') + /** * Save data to localStorage with error handling */ @@ -15,7 +18,7 @@ export function saveToStorage(key: string, data: T): boolean { localStorage.setItem(key, JSON.stringify(data)) return true } catch (error) { - console.error(`Failed to save data to ${key}:`, error) + logger.error(`Failed to save data to ${key}:`, { error }) return false } } @@ -28,7 +31,7 @@ export function loadFromStorage(key: string): T | null { const data = localStorage.getItem(key) return data ? JSON.parse(data) : null } catch (error) { - console.error(`Failed to load data from ${key}:`, error) + logger.error(`Failed to load data from ${key}:`, { error }) return null } } @@ -41,7 +44,7 @@ export function removeFromStorage(key: string): boolean { localStorage.removeItem(key) return true } catch (error) { - console.error(`Failed to remove data from ${key}:`, error) + logger.error(`Failed to remove data from ${key}:`, { error }) return false } } diff --git a/stores/workflows/registry/store.ts b/stores/workflows/registry/store.ts index 2a9cb9fde4..00256efe42 100644 --- a/stores/workflows/registry/store.ts +++ b/stores/workflows/registry/store.ts @@ -1,8 +1,8 @@ import { create } from 'zustand' import { devtools } from 'zustand/middleware' +import { createLogger } from '@/lib/logs/console-logger' import { API_ENDPOINTS, STORAGE_KEYS } from '../../constants' import { - loadRegistry, loadWorkflowState, removeFromStorage, saveRegistry, @@ -15,6 +15,8 @@ import { useWorkflowStore } from '../workflow/store' import { WorkflowMetadata, WorkflowRegistry } from './types' import { generateUniqueName, getNextWorkflowColor } from './utils' +const logger = createLogger('Workflow Registry') + export const useWorkflowRegistry = create()( devtools( (set, get) => ({ @@ -89,7 +91,7 @@ export const useWorkflowRegistry = create()( lastSaved: parsedState.lastSaved || Date.now(), }) - console.log(`Switched to workflow ${id}`) + logger.info(`Switched to workflow ${id}`) } else { // If no saved state, initialize with empty state useWorkflowStore.setState({ @@ -117,7 +119,7 @@ export const useWorkflowRegistry = create()( lastSaved: Date.now(), }) - console.warn(`No saved state found for workflow ${id}, initialized with empty state`) + logger.warn(`No saved state found for workflow ${id}, initialized with empty state`) } // Update the active workflow ID @@ -312,7 +314,7 @@ export const useWorkflowRegistry = create()( state: { blocks: {} }, // Empty blocks will signal to cancel the schedule }), }).catch((error) => { - console.error(`Error cancelling schedule for deleted workflow ${id}:`, error) + logger.error(`Error cancelling schedule for deleted workflow ${id}:`, { error }) }) // Sync deletion with database diff --git a/stores/workflows/sync.ts b/stores/workflows/sync.ts index fd46bc92d1..2afd87a3a2 100644 --- a/stores/workflows/sync.ts +++ b/stores/workflows/sync.ts @@ -1,5 +1,6 @@ 'use client' +import { createLogger } from '@/lib/logs/console-logger' import { getAllWorkflowsWithValues } from '.' import { API_ENDPOINTS } from '../constants' import { createSingletonSyncManager } from '../sync' @@ -7,7 +8,9 @@ import { useWorkflowRegistry } from './registry/store' import { WorkflowMetadata } from './registry/types' import { useSubBlockStore } from './subblock/store' import { useWorkflowStore } from './workflow/store' -import { BlockState, WorkflowState } from './workflow/types' +import { BlockState } from './workflow/types' + +const logger = createLogger('Workflows Sync') // Flag to prevent immediate sync back to DB after loading from DB let isLoadingFromDB = false @@ -52,7 +55,7 @@ async function updateWorkflowSchedule(workflowId: string, state: any): Promise { if (!response.ok) { if (response.status === 401) { - console.warn('User not authenticated for workflow fetch') + logger.warn('User not authenticated for workflow fetch') return } - console.error('Failed to fetch workflows:', response.statusText) + logger.error('Failed to fetch workflows:', response.statusText) return } const { data } = await response.json() if (!data || !Array.isArray(data) || data.length === 0) { - console.log('No workflows found in database') + logger.info('No workflows found in database') return } @@ -204,9 +207,9 @@ export async function fetchWorkflowsFromDB(): Promise { } } - console.log('Workflows loaded from DB:', Object.keys(registryWorkflows).length) + logger.info('Workflows loaded from DB:', Object.keys(registryWorkflows).length) } catch (error) { - console.error('Error fetching workflows from DB:', error) + logger.error('Error fetching workflows from DB:', { error }) } finally { // Reset the flag after a short delay to allow state to settle setTimeout(() => { @@ -223,7 +226,7 @@ export const workflowSync = createSingletonSyncManager('workflow-sync', () => ({ // Skip sync if we're currently loading from DB to prevent overwriting DB data if (isLoadingFromDB) { - console.log('Skipping workflow sync while loading from DB') + logger.info('Skipping workflow sync while loading from DB') return { skipSync: true } } @@ -232,7 +235,7 @@ export const workflowSync = createSingletonSyncManager('workflow-sync', () => ({ // Skip sync if there are no workflows to sync if (Object.keys(workflowsData).length === 0) { - console.log('Skipping workflow sync - no workflows to sync') + logger.info('Skipping workflow sync - no workflows to sync') return { skipSync: true } } @@ -244,7 +247,7 @@ export const workflowSync = createSingletonSyncManager('workflow-sync', () => ({ syncOnInterval: true, syncOnExit: true, onSyncSuccess: async (data) => { - console.log('Workflows synced to DB successfully') + logger.info('Workflows synced to DB successfully') // After successful sync to DB, update schedules for all workflows try { @@ -273,7 +276,7 @@ export const workflowSync = createSingletonSyncManager('workflow-sync', () => ({ } } } catch (error) { - console.error('Error updating workflow schedules:', error) + logger.error('Error updating workflow schedules:', { error }) } }, })) diff --git a/tools/docs/create.ts b/tools/docs/create.ts index 563ae08e3c..66bdb2de39 100644 --- a/tools/docs/create.ts +++ b/tools/docs/create.ts @@ -1,6 +1,9 @@ +import { createLogger } from '@/lib/logs/console-logger' import { ToolConfig } from '../types' import { GoogleDocsCreateResponse, GoogleDocsToolParams } from './types' +const logger = createLogger('Google Docs Create Tool') + export const createTool: ToolConfig = { id: 'google_docs_create', name: 'Create Google Docs Document', @@ -55,7 +58,6 @@ export const createTool: ToolConfig { if (!response.ok) { const error = await response.json() - console.error('Google Drive export error:', { + logger.error('Google Drive export error:', { status: response.status, statusText: response.statusText, error, @@ -54,7 +57,7 @@ export const exportTool: ToolConfig< if (!metadataResponse.ok) { const metadataError = await metadataResponse.json() - console.error('Google Drive metadata error:', { + logger.error('Google Drive metadata error:', { status: metadataResponse.status, statusText: metadataResponse.statusText, error: metadataError, @@ -69,7 +72,7 @@ export const exportTool: ToolConfig< try { content = await response.text() } catch (error: any) { - console.error('Error reading response content:', { + logger.error('Error reading response content:', { message: error.message, stack: error.stack, error: JSON.stringify(error), @@ -96,7 +99,7 @@ export const exportTool: ToolConfig< } }, transformError: (error: any) => { - console.error('Export tool error:', { + logger.error('Export tool error:', { message: error.message, stack: error.stack, error: JSON.stringify(error, null, 2), diff --git a/tools/index.ts b/tools/index.ts index 9291e72d6a..39660a9b1b 100644 --- a/tools/index.ts +++ b/tools/index.ts @@ -1,3 +1,4 @@ +import { createLogger } from '@/lib/logs/console-logger' import { useCustomToolsStore } from '@/stores/custom-tools/store' import { useEnvironmentStore } from '@/stores/settings/environment/store' import { docsCreateTool, docsReadTool, docsWriteTool } from './docs' @@ -34,6 +35,8 @@ import { whatsappSendMessageTool } from './whatsapp' import { xReadTool, xSearchTool, xUserTool, xWriteTool } from './x' import { youtubeSearchTool } from './youtube/search' +const logger = createLogger('Tools') + // Registry of all available tools export const tools: Record = { openai_embeddings: openAIEmbeddings, @@ -130,7 +133,7 @@ function getCustomTool(customToolId: string): ToolConfig | undefined { } if (!customTool) { - console.error(`Custom tool not found: ${identifier}`) + logger.error(`Custom tool not found: ${identifier}`) return undefined } @@ -255,7 +258,7 @@ function getCustomTool(customToolId: string): ToolConfig | undefined { error: undefined, } } catch (error: any) { - console.warn('WebContainer execution failed, falling back to API:', error.message) + logger.warn('WebContainer execution failed, falling back to API:', error.message) // Fall back to API route if WebContainer fails return undefined } @@ -320,7 +323,7 @@ export async function executeTool( try { return await tool.postProcess(result, params, executeTool) } catch (error) { - console.error(`Error in post-processing for tool ${toolId}:`, error) + logger.error(`Error in post-processing for tool ${toolId}:`, { error }) // Return original result if post-processing fails return result } @@ -337,7 +340,7 @@ export async function executeTool( try { return await tool.postProcess(result, params, executeTool) } catch (error) { - console.error(`Error in post-processing for tool ${toolId}:`, error) + logger.error(`Error in post-processing for tool ${toolId}:`, { error }) // Return original result if post-processing fails return result } @@ -345,7 +348,7 @@ export async function executeTool( return result } catch (error: any) { - console.error(`Error executing tool ${toolId}:`, error) + logger.error(`Error executing tool ${toolId}:`, { error }) // For custom tools, provide more helpful error information if (toolId.startsWith('custom_')) { @@ -353,8 +356,8 @@ export async function executeTool( const allTools = useCustomToolsStore.getState().getAllTools() const availableTools = allTools.map((t) => ({ id: t.id, title: t.title })) - console.error('Available custom tools:', availableTools) - console.error(`Looking for custom tool with identifier: ${identifier}`) + logger.error('Available custom tools:', availableTools) + logger.error(`Looking for custom tool with identifier: ${identifier}`) } return { @@ -428,7 +431,7 @@ async function handleInternalRequest( error: undefined, } } catch (error: any) { - console.error(`Error executing internal tool ${toolId}:`, error) + logger.error(`Error executing internal tool ${toolId}:`, { error }) // Use the tool's error transformer if available if (tool.transformError) { @@ -474,7 +477,7 @@ async function handleInternalRequest( } } } catch (transformError) { - console.error(`Error transforming error for tool ${toolId}:`, transformError) + logger.error(`Error transforming error for tool ${toolId}:`, { transformError }) return { success: false, output: {}, @@ -573,7 +576,7 @@ async function handleProxyRequest( if (!response.ok) { const errorText = await response.text() - console.error('Token fetch failed:', response.status, errorText) + logger.error('Token fetch failed:', response.status, errorText) throw new Error(`Failed to fetch access token: ${response.status} ${errorText}`) } @@ -584,7 +587,7 @@ async function handleProxyRequest( delete params.credential if (params.workflowId) delete params.workflowId } catch (error) { - console.error('Error fetching access token:', error) + logger.error('Error fetching access token:', { error }) throw error } } diff --git a/tools/supabase/insert.ts b/tools/supabase/insert.ts index 4acabc4d78..7623799722 100644 --- a/tools/supabase/insert.ts +++ b/tools/supabase/insert.ts @@ -31,12 +31,6 @@ export const insertTool: ToolConfig { try { - // This is a mock implementation - console.log( - `Inserting data into Supabase table ${params.table} in project ${params.projectId}` - ) - console.log('Data to insert:', params.data) - // Mock response const mockData = [{ ...params.data, id: Math.floor(Math.random() * 1000) }] @@ -50,7 +44,6 @@ export const insertTool: ToolConfig = }, directExecution: async (params: SupabaseQueryParams) => { try { - // This is a mock implementation - console.log(`Querying Supabase table ${params.table} in project ${params.projectId}`) - // Mock response const mockData = [ { id: 1, name: 'Item 1', description: 'Description 1' }, @@ -52,7 +49,6 @@ export const queryTool: ToolConfig = error: null, } } catch (error) { - console.error('Error querying Supabase:', error) return { success: false, output: { diff --git a/tools/supabase/update.ts b/tools/supabase/update.ts index 7f4293ba78..8c312a3cf9 100644 --- a/tools/supabase/update.ts +++ b/tools/supabase/update.ts @@ -33,11 +33,6 @@ export const updateTool: ToolConfig { try { - // This is a mock implementation - console.log(`Updating data in Supabase table ${params.table} in project ${params.projectId}`) - console.log('Filter:', params.filter) - console.log('Data to update:', params.data) - // Mock response const mockData = [{ ...params.data, id: params.filter.value }] @@ -51,7 +46,6 @@ export const updateTool: ToolConfig = { id: 'whatsapp', name: 'WhatsApp', @@ -81,7 +84,7 @@ export const sendMessageTool: ToolConfig = { if (!response.ok) { const errorMessage = data.error?.message || `Failed to send WhatsApp message (HTTP ${response.status})` - console.error('WhatsApp API error:', data) + logger.error('WhatsApp API error:', data) throw new Error(errorMessage) } @@ -96,7 +99,7 @@ export const sendMessageTool: ToolConfig = { }, transformError: (error) => { - console.error('WhatsApp tool error:', error) + logger.error('WhatsApp tool error:', { error }) return `WhatsApp message failed: ${error.message || 'Unknown error occurred'}` }, }