Skip to content

Commit 103b31a

Browse files
authored
fix(stores): remove dead code causing log spam on startup (#2927)
* fix(stores): remove dead code causing log spam on startup * fix(stores): replace custom tools zustand store with react query cache
1 parent 004e058 commit 103b31a

File tree

12 files changed

+120
-306
lines changed

12 files changed

+120
-306
lines changed

apps/sim/executor/handlers/agent/agent-handler.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -347,18 +347,18 @@ export class AgentBlockHandler implements BlockHandler {
347347
): Promise<{ schema: any; code: string; title: string } | null> {
348348
if (typeof window !== 'undefined') {
349349
try {
350-
const { useCustomToolsStore } = await import('@/stores/custom-tools')
351-
const tool = useCustomToolsStore.getState().getTool(customToolId)
350+
const { getCustomTool } = await import('@/hooks/queries/custom-tools')
351+
const tool = getCustomTool(customToolId, ctx.workspaceId)
352352
if (tool) {
353353
return {
354354
schema: tool.schema,
355355
code: tool.code || '',
356356
title: tool.title,
357357
}
358358
}
359-
logger.warn(`Custom tool not found in store: ${customToolId}`)
359+
logger.warn(`Custom tool not found in cache: ${customToolId}`)
360360
} catch (error) {
361-
logger.error('Error accessing custom tools store:', { error })
361+
logger.error('Error accessing custom tools cache:', { error })
362362
}
363363
}
364364

apps/sim/hooks/queries/custom-tools.ts

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,34 @@
11
import { createLogger } from '@sim/logger'
22
import { keepPreviousData, useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
3-
import type { CustomToolDefinition, CustomToolSchema } from '@/stores/custom-tools'
4-
import { useCustomToolsStore } from '@/stores/custom-tools'
3+
import { getQueryClient } from '@/app/_shell/providers/query-provider'
54

65
const logger = createLogger('CustomToolsQueries')
76
const API_ENDPOINT = '/api/tools/custom'
87

8+
export interface CustomToolSchema {
9+
type: string
10+
function: {
11+
name: string
12+
description?: string
13+
parameters: {
14+
type: string
15+
properties: Record<string, unknown>
16+
required?: string[]
17+
}
18+
}
19+
}
20+
21+
export interface CustomToolDefinition {
22+
id: string
23+
workspaceId: string | null
24+
userId: string | null
25+
title: string
26+
schema: CustomToolSchema
27+
code: string
28+
createdAt: string
29+
updatedAt?: string
30+
}
31+
932
/**
1033
* Query key factories for custom tools queries
1134
*/
@@ -64,8 +87,38 @@ function normalizeCustomTool(tool: ApiCustomTool, workspaceId: string): CustomTo
6487
}
6588
}
6689

67-
function syncCustomToolsToStore(tools: CustomToolDefinition[]) {
68-
useCustomToolsStore.getState().setTools(tools)
90+
/**
91+
* Extract workspaceId from the current URL path
92+
* Expected format: /workspace/{workspaceId}/...
93+
*/
94+
function getWorkspaceIdFromUrl(): string | null {
95+
if (typeof window === 'undefined') return null
96+
const match = window.location.pathname.match(/^\/workspace\/([^/]+)/)
97+
return match?.[1] ?? null
98+
}
99+
100+
/**
101+
* Get all custom tools from the query cache (for non-React code)
102+
* If workspaceId is not provided, extracts it from the current URL
103+
*/
104+
export function getCustomTools(workspaceId?: string): CustomToolDefinition[] {
105+
if (typeof window === 'undefined') return []
106+
const wsId = workspaceId ?? getWorkspaceIdFromUrl()
107+
if (!wsId) return []
108+
const queryClient = getQueryClient()
109+
return queryClient.getQueryData<CustomToolDefinition[]>(customToolsKeys.list(wsId)) ?? []
110+
}
111+
112+
/**
113+
* Get a specific custom tool from the query cache by ID (for non-React code)
114+
* If workspaceId is not provided, extracts it from the current URL
115+
*/
116+
export function getCustomTool(
117+
toolId: string,
118+
workspaceId?: string
119+
): CustomToolDefinition | undefined {
120+
const tools = getCustomTools(workspaceId)
121+
return tools.find((tool) => tool.id === toolId) || tools.find((tool) => tool.title === toolId)
69122
}
70123

71124
/**
@@ -134,19 +187,13 @@ async function fetchCustomTools(workspaceId: string): Promise<CustomToolDefiniti
134187
* Hook to fetch custom tools
135188
*/
136189
export function useCustomTools(workspaceId: string) {
137-
const query = useQuery<CustomToolDefinition[]>({
190+
return useQuery<CustomToolDefinition[]>({
138191
queryKey: customToolsKeys.list(workspaceId),
139192
queryFn: () => fetchCustomTools(workspaceId),
140193
enabled: !!workspaceId,
141194
staleTime: 60 * 1000, // 1 minute - tools don't change frequently
142195
placeholderData: keepPreviousData,
143196
})
144-
145-
if (query.data) {
146-
syncCustomToolsToStore(query.data)
147-
}
148-
149-
return query
150197
}
151198

152199
/**

apps/sim/hooks/use-collaborative-workflow.ts

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,6 @@ export function useCollaborativeWorkflow() {
113113
const {
114114
isConnected,
115115
currentWorkflowId,
116-
presenceUsers,
117-
joinWorkflow,
118-
leaveWorkflow,
119116
emitWorkflowOperation,
120117
emitSubblockUpdate,
121118
emitVariableUpdate,
@@ -143,13 +140,7 @@ export function useCollaborativeWorkflow() {
143140
// Track if we're applying remote changes to avoid infinite loops
144141
const isApplyingRemoteChange = useRef(false)
145142

146-
// Track last applied position timestamps to prevent out-of-order updates
147-
const lastPositionTimestamps = useRef<Map<string, number>>(new Map())
148-
149-
// Operation queue
150143
const {
151-
queue,
152-
hasOperationError,
153144
addToQueue,
154145
confirmOperation,
155146
failOperation,
@@ -161,22 +152,6 @@ export function useCollaborativeWorkflow() {
161152
return !!currentWorkflowId && activeWorkflowId === currentWorkflowId
162153
}, [currentWorkflowId, activeWorkflowId])
163154

164-
// Clear position timestamps when switching workflows
165-
// Note: Workflow joining is now handled automatically by socket connect event based on URL
166-
useEffect(() => {
167-
if (activeWorkflowId && currentWorkflowId !== activeWorkflowId) {
168-
logger.info(`Active workflow changed to: ${activeWorkflowId}`, {
169-
isConnected,
170-
currentWorkflowId,
171-
activeWorkflowId,
172-
presenceUsers: presenceUsers.length,
173-
})
174-
175-
// Clear position timestamps when switching workflows
176-
lastPositionTimestamps.current.clear()
177-
}
178-
}, [activeWorkflowId, isConnected, currentWorkflowId])
179-
180155
// Register emit functions with operation queue store
181156
useEffect(() => {
182157
registerEmitFunctions(
@@ -1621,15 +1596,8 @@ export function useCollaborativeWorkflow() {
16211596
)
16221597

16231598
return {
1624-
// Connection status
16251599
isConnected,
16261600
currentWorkflowId,
1627-
presenceUsers,
1628-
hasOperationError,
1629-
1630-
// Workflow management
1631-
joinWorkflow,
1632-
leaveWorkflow,
16331601

16341602
// Collaborative operations
16351603
collaborativeBatchUpdatePositions,

apps/sim/lib/copilot/tools/client/workflow/manage-custom-tool.ts

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
type BaseClientToolMetadata,
77
ClientToolCallState,
88
} from '@/lib/copilot/tools/client/base-tool'
9-
import { useCustomToolsStore } from '@/stores/custom-tools'
9+
import { getCustomTool } from '@/hooks/queries/custom-tools'
1010
import { useCopilotStore } from '@/stores/panel/copilot/store'
1111
import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
1212

@@ -83,17 +83,15 @@ export class ManageCustomToolClientTool extends BaseClientTool {
8383
getDynamicText: (params, state) => {
8484
const operation = params?.operation as 'add' | 'edit' | 'delete' | 'list' | undefined
8585

86-
// Return undefined if no operation yet - use static defaults
8786
if (!operation) return undefined
8887

89-
// Get tool name from schema, or look it up from the store by toolId
9088
let toolName = params?.schema?.function?.name
9189
if (!toolName && params?.toolId) {
9290
try {
93-
const tool = useCustomToolsStore.getState().getTool(params.toolId)
91+
const tool = getCustomTool(params.toolId)
9492
toolName = tool?.schema?.function?.name
9593
} catch {
96-
// Ignore errors accessing store
94+
// Ignore errors accessing cache
9795
}
9896
}
9997

@@ -168,7 +166,6 @@ export class ManageCustomToolClientTool extends BaseClientTool {
168166
* Add operations execute directly without confirmation.
169167
*/
170168
getInterruptDisplays(): BaseClientToolMetadata['interrupt'] | undefined {
171-
// Try currentArgs first, then fall back to store (for when called before execute())
172169
const args = this.currentArgs || this.getArgsFromStore()
173170
const operation = args?.operation
174171
if (operation === 'edit' || operation === 'delete') {
@@ -199,12 +196,9 @@ export class ManageCustomToolClientTool extends BaseClientTool {
199196

200197
async execute(args?: ManageCustomToolArgs): Promise<void> {
201198
this.currentArgs = args
202-
// For add and list operations, execute directly without confirmation
203-
// For edit/delete, the copilot store will check hasInterrupt() and wait for confirmation
204199
if (args?.operation === 'add' || args?.operation === 'list') {
205200
await this.handleAccept(args)
206201
}
207-
// edit/delete will wait for user confirmation via handleAccept
208202
}
209203

210204
/**
@@ -222,7 +216,6 @@ export class ManageCustomToolClientTool extends BaseClientTool {
222216

223217
const { operation, toolId, schema, code } = args
224218

225-
// Get workspace ID from the workflow registry
226219
const { hydration } = useWorkflowRegistry.getState()
227220
const workspaceId = hydration.workspaceId
228221
if (!workspaceId) {
@@ -247,7 +240,6 @@ export class ManageCustomToolClientTool extends BaseClientTool {
247240
await this.deleteCustomTool({ toolId, workspaceId }, logger)
248241
break
249242
case 'list':
250-
// List operation is read-only, just mark as complete
251243
await this.markToolComplete(200, 'Listed custom tools')
252244
break
253245
default:
@@ -326,13 +318,10 @@ export class ManageCustomToolClientTool extends BaseClientTool {
326318
throw new Error('Tool ID is required for editing a custom tool')
327319
}
328320

329-
// At least one of schema or code must be provided
330321
if (!schema && !code) {
331322
throw new Error('At least one of schema or code must be provided for editing')
332323
}
333324

334-
// We need to send the full tool data to the API for updates
335-
// First, fetch the existing tool to merge with updates
336325
const existingResponse = await fetch(`${API_ENDPOINT}?workspaceId=${workspaceId}`)
337326
const existingData = await existingResponse.json()
338327

@@ -345,7 +334,6 @@ export class ManageCustomToolClientTool extends BaseClientTool {
345334
throw new Error(`Tool with ID ${toolId} not found`)
346335
}
347336

348-
// Merge updates with existing tool - use function name as title
349337
const mergedSchema = schema ?? existingTool.schema
350338
const updatedTool = {
351339
id: toolId,

apps/sim/providers/utils.test.ts

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
getAllProviderIds,
1212
getApiKey,
1313
getBaseModelProviders,
14-
getCustomTools,
1514
getHostedModels,
1615
getMaxTemperature,
1716
getProvider,
@@ -30,7 +29,6 @@ import {
3029
shouldBillModelUsage,
3130
supportsTemperature,
3231
supportsToolUsageControl,
33-
transformCustomTool,
3432
updateOllamaProviderModels,
3533
} from '@/providers/utils'
3634

@@ -837,51 +835,6 @@ describe('JSON and Structured Output', () => {
837835
})
838836

839837
describe('Tool Management', () => {
840-
describe('transformCustomTool', () => {
841-
it.concurrent('should transform valid custom tool schema', () => {
842-
const customTool = {
843-
id: 'test-tool',
844-
schema: {
845-
function: {
846-
name: 'testFunction',
847-
description: 'A test function',
848-
parameters: {
849-
type: 'object',
850-
properties: {
851-
input: { type: 'string', description: 'Input parameter' },
852-
},
853-
required: ['input'],
854-
},
855-
},
856-
},
857-
}
858-
859-
const result = transformCustomTool(customTool)
860-
861-
expect(result.id).toBe('custom_test-tool')
862-
expect(result.name).toBe('testFunction')
863-
expect(result.description).toBe('A test function')
864-
expect(result.parameters.type).toBe('object')
865-
expect(result.parameters.properties).toBeDefined()
866-
expect(result.parameters.required).toEqual(['input'])
867-
})
868-
869-
it.concurrent('should throw error for invalid schema', () => {
870-
const invalidTool = { id: 'test', schema: null }
871-
expect(() => transformCustomTool(invalidTool)).toThrow('Invalid custom tool schema')
872-
873-
const noFunction = { id: 'test', schema: {} }
874-
expect(() => transformCustomTool(noFunction)).toThrow('Invalid custom tool schema')
875-
})
876-
})
877-
878-
describe('getCustomTools', () => {
879-
it.concurrent('should return array of transformed custom tools', () => {
880-
const result = getCustomTools()
881-
expect(Array.isArray(result)).toBe(true)
882-
})
883-
})
884-
885838
describe('prepareToolsWithUsageControl', () => {
886839
const mockLogger = {
887840
info: vi.fn(),

apps/sim/providers/utils.ts

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import {
2828
updateOllamaModels as updateOllamaModelsInDefinitions,
2929
} from '@/providers/models'
3030
import type { ProviderId, ProviderToolConfig } from '@/providers/types'
31-
import { useCustomToolsStore } from '@/stores/custom-tools/store'
3231
import { useProvidersStore } from '@/stores/providers/store'
3332
import { mergeToolParameters } from '@/tools/params'
3433

@@ -419,38 +418,6 @@ export function extractAndParseJSON(content: string): any {
419418
}
420419
}
421420

422-
/**
423-
* Transforms a custom tool schema into a provider tool config
424-
*/
425-
export function transformCustomTool(customTool: any): ProviderToolConfig {
426-
const schema = customTool.schema
427-
428-
if (!schema || !schema.function) {
429-
throw new Error('Invalid custom tool schema')
430-
}
431-
432-
return {
433-
id: `custom_${customTool.id}`,
434-
name: schema.function.name,
435-
description: schema.function.description || '',
436-
params: {},
437-
parameters: {
438-
type: schema.function.parameters.type,
439-
properties: schema.function.parameters.properties,
440-
required: schema.function.parameters.required || [],
441-
},
442-
}
443-
}
444-
445-
/**
446-
* Gets all available custom tools as provider tool configs
447-
*/
448-
export function getCustomTools(): ProviderToolConfig[] {
449-
const customTools = useCustomToolsStore.getState().getAllTools()
450-
451-
return customTools.map(transformCustomTool)
452-
}
453-
454421
/**
455422
* Transforms a block tool into a provider tool config with operation selection
456423
*

apps/sim/stores/custom-tools/index.ts

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)