Skip to content

Commit b0b814e

Browse files
committed
more cases
1 parent fed57aa commit b0b814e

19 files changed

Lines changed: 1626 additions & 144 deletions

File tree

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/eval-input/eval-input.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Button, Input, Textarea, Tooltip } from '@/components/emcn'
55
import { Trash } from '@/components/emcn/icons/trash'
66
import { Label } from '@/components/ui/label'
77
import { cn } from '@/lib/core/utils/cn'
8+
import { WORKFLOW_SEARCH_HIGHLIGHT_CLASS } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/constants'
89
import { formatDisplayText } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/formatted-text'
910
import { TagDropdown } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tag-dropdown/tag-dropdown'
1011
import { useSubBlockInput } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-input'
@@ -31,9 +32,6 @@ interface EvalInputProps {
3132
activeSearchTarget?: ActiveSearchTarget | null
3233
}
3334

34-
const WORKFLOW_SEARCH_HIGHLIGHT_CLASS =
35-
'rounded-sm bg-orange-400 shadow-[3px_0_0_#fb923c,-3px_0_0_#fb923c]'
36-
3735
// Default values
3836
const createDefaultMetric = (): EvalMetric => ({
3937
id: generateId(),

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/starter/input-format.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
} from '@/components/emcn'
2121
import { Label } from '@/components/ui/label'
2222
import { cn } from '@/lib/core/utils/cn'
23+
import { WORKFLOW_SEARCH_HIGHLIGHT_CLASS } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/constants'
2324
import { formatDisplayText } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/formatted-text'
2425
import { TagDropdown } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tag-dropdown/tag-dropdown'
2526
import { useSubBlockInput } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/hooks/use-sub-block-input'
@@ -53,9 +54,6 @@ interface FieldFormatProps {
5354
activeSearchTarget?: ActiveSearchTarget | null
5455
}
5556

56-
const WORKFLOW_SEARCH_HIGHLIGHT_CLASS =
57-
'rounded-sm bg-orange-400 shadow-[3px_0_0_#fb923c,-3px_0_0_#fb923c]'
58-
5957
/**
6058
* Type options for field type selection
6159
*/

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/tool-input.tsx

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ import { useWorkflowStore } from '@/stores/workflows/workflow/store'
7777
import {
7878
formatParameterLabel,
7979
getSubBlocksForToolInput,
80+
getToolIdForOperation,
8081
getToolParametersConfig,
8182
isPasswordParameter,
8283
type SubBlocksForToolInput,
@@ -383,36 +384,6 @@ function getOperationOptions(blockType: string): { label: string; id: string }[]
383384
})
384385
}
385386

386-
/**
387-
* Gets the correct tool ID for a given operation.
388-
*
389-
* @param blockType - The block type
390-
* @param operation - The selected operation (for multi-operation tools)
391-
* @returns The tool ID to use for execution, or `undefined` if not found
392-
*/
393-
function getToolIdForOperation(blockType: string, operation?: string): string | undefined {
394-
const block = getAllBlocks().find((b) => b.type === blockType)
395-
if (!block || !block.tools?.access) return undefined
396-
397-
if (block.tools.access.length === 1) {
398-
return block.tools.access[0]
399-
}
400-
401-
if (operation && block.tools?.config?.tool) {
402-
try {
403-
return block.tools.config.tool({ operation })
404-
} catch (error) {
405-
logger.error('Error selecting tool for operation:', error)
406-
}
407-
}
408-
409-
if (operation && block.tools.access.includes(operation)) {
410-
return operation
411-
}
412-
413-
return block.tools.access[0]
414-
}
415-
416387
/**
417388
* Creates a styled icon element for tool items in the selection dropdown.
418389
*
Original file line numberDiff line numberDiff line change
@@ -1,36 +1 @@
1-
/**
2-
* Represents a tool selected and configured in the workflow
3-
*
4-
* @remarks
5-
* Valid types include:
6-
* - Standard block types (e.g., 'api', 'search', 'function')
7-
* - 'custom-tool': User-defined tools with custom code
8-
* - 'mcp': Individual MCP tool from a connected server
9-
*
10-
* For custom tools (new format), we only store: type, customToolId, usageControl, isExpanded.
11-
* Everything else (title, schema, code) is loaded dynamically from the database.
12-
* Legacy custom tools with inline schema/code are still supported for backwards compatibility.
13-
*/
14-
export interface StoredTool {
15-
/** Block type identifier */
16-
type: string
17-
/** Display title for the tool (optional for new custom tool format) */
18-
title?: string
19-
/** Direct tool ID for execution (optional for new custom tool format) */
20-
toolId?: string
21-
/** Parameter values configured by the user */
22-
params?: Record<string, string>
23-
/** Whether the tool details are expanded in UI */
24-
isExpanded?: boolean
25-
/** Database ID for custom tools (new format - reference only) */
26-
customToolId?: string
27-
/** Tool schema for custom tools (legacy format - inline JSON schema) */
28-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
29-
schema?: Record<string, any>
30-
/** Implementation code for custom tools (legacy format - inline) */
31-
code?: string
32-
/** Selected operation for multi-operation tools */
33-
operation?: string
34-
/** Tool usage control mode for LLM */
35-
usageControl?: 'auto' | 'force' | 'none'
36-
}
1+
export type { StoredTool } from '@/lib/workflows/tool-input/types'

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/search-replace/hooks/use-workflow-resource-replacement-options.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export function useWorkflowResourceReplacementOptions({
2727
workflowId,
2828
}: UseWorkflowResourceReplacementOptionsParams): WorkflowSearchReplacementOption[] {
2929
const oauthOptions = useWorkflowSearchOAuthReplacementOptions(matches, workspaceId, workflowId)
30-
const knowledgeOptions = useWorkflowSearchKnowledgeReplacementOptions(workspaceId)
30+
const knowledgeOptions = useWorkflowSearchKnowledgeReplacementOptions(matches, workspaceId)
3131
const selectorOptions = useWorkflowSearchSelectorReplacementOptions(matches)
3232
const tableOptions = useWorkflowSearchTableReplacementOptions(matches, workspaceId)
3333
const fileOptions = useWorkflowSearchFileReplacementOptions(matches, workspaceId)

apps/sim/hooks/queries/workflow-search-replace.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,22 +73,16 @@ export const workflowSearchReplaceKeys = {
7373
tableReplacementOptions: (workspaceId?: string) =>
7474
[...workflowSearchReplaceKeys.replacementOptions(), 'table', workspaceId ?? ''] as const,
7575
fileDetails: () => [...workflowSearchReplaceKeys.resourceDetails(), 'file'] as const,
76-
fileDetail: (workspaceId?: string, fileKey?: string) =>
77-
[...workflowSearchReplaceKeys.fileDetails(), workspaceId ?? '', fileKey ?? ''] as const,
7876
fileListDetails: (workspaceId?: string) =>
7977
[...workflowSearchReplaceKeys.fileDetails(), 'list', workspaceId ?? ''] as const,
8078
fileReplacementOptions: (workspaceId?: string) =>
8179
[...workflowSearchReplaceKeys.replacementOptions(), 'file', workspaceId ?? ''] as const,
8280
mcpServerDetails: () => [...workflowSearchReplaceKeys.resourceDetails(), 'mcp-server'] as const,
83-
mcpServerDetail: (workspaceId?: string, serverId?: string) =>
84-
[...workflowSearchReplaceKeys.mcpServerDetails(), workspaceId ?? '', serverId ?? ''] as const,
8581
mcpServerListDetails: (workspaceId?: string) =>
8682
[...workflowSearchReplaceKeys.mcpServerDetails(), 'list', workspaceId ?? ''] as const,
8783
mcpServerReplacementOptions: (workspaceId?: string) =>
8884
[...workflowSearchReplaceKeys.replacementOptions(), 'mcp-server', workspaceId ?? ''] as const,
8985
mcpToolDetails: () => [...workflowSearchReplaceKeys.resourceDetails(), 'mcp-tool'] as const,
90-
mcpToolDetail: (workspaceId?: string, toolId?: string) =>
91-
[...workflowSearchReplaceKeys.mcpToolDetails(), workspaceId ?? '', toolId ?? ''] as const,
9286
mcpToolListDetails: (workspaceId?: string) =>
9387
[...workflowSearchReplaceKeys.mcpToolDetails(), 'list', workspaceId ?? ''] as const,
9488
mcpToolReplacementOptions: (workspaceId?: string) =>
@@ -439,22 +433,33 @@ export function useWorkflowSearchOAuthReplacementOptions(
439433
})
440434
}
441435

442-
export function useWorkflowSearchKnowledgeReplacementOptions(workspaceId?: string) {
436+
export function useWorkflowSearchKnowledgeReplacementOptions(
437+
matches: WorkflowSearchMatch[],
438+
workspaceId?: string
439+
) {
440+
const knowledgeGroups = useMemo(
441+
() => uniqueResourceOptionGroups(matches, 'knowledge-base'),
442+
[matches]
443+
)
444+
443445
return useQueries({
444446
queries: [
445447
{
446448
queryKey: workflowSearchReplaceKeys.knowledgeReplacementOptions(workspaceId),
447449
queryFn: ({ signal }: { signal: AbortSignal }) =>
448450
fetchKnowledgeBases(workspaceId, 'active', signal),
449-
enabled: Boolean(workspaceId),
451+
enabled: Boolean(workspaceId && knowledgeGroups.length > 0),
450452
staleTime: 60 * 1000,
451453
placeholderData: (previous: KnowledgeBaseData[] | undefined) => previous,
452454
select: (knowledgeBases: KnowledgeBaseData[]): WorkflowSearchReplacementOption[] =>
453-
knowledgeBases.map((knowledgeBase) => ({
454-
kind: 'knowledge-base',
455-
value: knowledgeBase.id,
456-
label: knowledgeBase.name,
457-
})),
455+
knowledgeGroups.flatMap((match) =>
456+
knowledgeBases.map((knowledgeBase) => ({
457+
kind: 'knowledge-base',
458+
value: knowledgeBase.id,
459+
label: knowledgeBase.name,
460+
resourceGroupKey: match.resource?.resourceGroupKey,
461+
}))
462+
),
458463
},
459464
],
460465
})

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ import { useShallow } from 'zustand/react/shallow'
1818
import { requestJson } from '@/lib/api/client/request'
1919
import { getWorkflowStateContract } from '@/lib/api/contracts'
2020
import { useSession } from '@/lib/auth/auth-client'
21+
import {
22+
type WorkflowSearchSubflowFieldId,
23+
workflowSearchSubflowFieldMatchesExpected,
24+
} from '@/lib/workflows/search-replace/subflow-fields'
2125
import { useSocket } from '@/app/workspace/providers/socket-provider'
2226
import { getBlock } from '@/blocks'
2327
import { getSubBlocksDependingOnChange } from '@/blocks/utils'
@@ -1543,7 +1547,7 @@ export function useCollaborativeWorkflow() {
15431547
subflowUpdates?: Array<{
15441548
blockId: string
15451549
blockType: 'loop' | 'parallel'
1546-
fieldId: string
1550+
fieldId: WorkflowSearchSubflowFieldId
15471551
before: unknown
15481552
after: unknown
15491553
}>
@@ -1580,6 +1584,23 @@ export function useCollaborativeWorkflow() {
15801584
return false
15811585
}
15821586

1587+
const staleSubflowUpdate = undoSubflowUpdates.find((update) => {
1588+
const currentBlock = useWorkflowStore.getState().blocks[update.blockId]
1589+
if (!currentBlock || currentBlock.type !== update.blockType) return true
1590+
return !workflowSearchSubflowFieldMatchesExpected(
1591+
currentBlock,
1592+
update.fieldId,
1593+
update.before
1594+
)
1595+
})
1596+
if (staleSubflowUpdate) {
1597+
logger.warn('Skipping batch subflow update because expected value changed', {
1598+
blockId: staleSubflowUpdate.blockId,
1599+
fieldId: staleSubflowUpdate.fieldId,
1600+
})
1601+
return false
1602+
}
1603+
15831604
if (updates.length > 0) {
15841605
updates.forEach((update) => {
15851606
useSubBlockStore.getState().setValue(update.blockId, update.subblockId, update.value)

0 commit comments

Comments
 (0)