mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-09 15:07:55 -05:00
fix(tool-input): allow multiple instances of workflow block or kb tools as agent tools (#2495)
* fix(tool-input): allow multiple instances of workflow block or kb tools as agent tools * ack PR comments
This commit is contained in:
@@ -982,6 +982,11 @@ export function ToolInput({
|
||||
if (hasMultipleOperations(blockType)) {
|
||||
return false
|
||||
}
|
||||
// Allow multiple instances for workflow and knowledge blocks
|
||||
// Each instance can target a different workflow/knowledge base
|
||||
if (blockType === 'workflow' || blockType === 'knowledge') {
|
||||
return false
|
||||
}
|
||||
return selectedTools.some((tool) => tool.toolId === toolId)
|
||||
}
|
||||
|
||||
|
||||
@@ -720,8 +720,10 @@ const PopoverSearch = React.forwardRef<HTMLDivElement, PopoverSearchProps>(
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
setSearchQuery('')
|
||||
onValueChange?.('')
|
||||
inputRef.current?.focus()
|
||||
}, [])
|
||||
}, [setSearchQuery, onValueChange])
|
||||
|
||||
return (
|
||||
<div ref={ref} className={cn('flex items-center px-[8px] py-[6px]', className)} {...props}>
|
||||
|
||||
@@ -479,8 +479,16 @@ export async function transformBlockTool(
|
||||
|
||||
const llmSchema = await createLLMToolSchema(toolConfig, userProvidedParams)
|
||||
|
||||
// Create unique tool ID by appending resource ID for multi-instance tools
|
||||
let uniqueToolId = toolConfig.id
|
||||
if (toolId === 'workflow_executor' && userProvidedParams.workflowId) {
|
||||
uniqueToolId = `${toolConfig.id}_${userProvidedParams.workflowId}`
|
||||
} else if (toolId.startsWith('knowledge_') && userProvidedParams.knowledgeBaseId) {
|
||||
uniqueToolId = `${toolConfig.id}_${userProvidedParams.knowledgeBaseId}`
|
||||
}
|
||||
|
||||
return {
|
||||
id: toolConfig.id,
|
||||
id: uniqueToolId,
|
||||
name: toolConfig.name,
|
||||
description: toolConfig.description,
|
||||
params: userProvidedParams,
|
||||
|
||||
@@ -16,6 +16,26 @@ import {
|
||||
|
||||
const logger = createLogger('Tools')
|
||||
|
||||
/**
|
||||
* Normalizes a tool ID by stripping resource ID suffix (UUID).
|
||||
* Workflow tools: 'workflow_executor_<uuid>' -> 'workflow_executor'
|
||||
* Knowledge tools: 'knowledge_search_<uuid>' -> 'knowledge_search'
|
||||
*/
|
||||
function normalizeToolId(toolId: string): string {
|
||||
// Check for workflow_executor_<uuid> pattern
|
||||
if (toolId.startsWith('workflow_executor_') && toolId.length > 'workflow_executor_'.length) {
|
||||
return 'workflow_executor'
|
||||
}
|
||||
// Check for knowledge_<operation>_<uuid> pattern
|
||||
const knowledgeOps = ['knowledge_search', 'knowledge_upload_chunk', 'knowledge_create_document']
|
||||
for (const op of knowledgeOps) {
|
||||
if (toolId.startsWith(`${op}_`) && toolId.length > op.length + 1) {
|
||||
return op
|
||||
}
|
||||
}
|
||||
return toolId
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum request body size in bytes before we warn/error about size limits.
|
||||
* Next.js 16 has a default middleware/proxy body limit of 10MB.
|
||||
@@ -186,20 +206,29 @@ export async function executeTool(
|
||||
try {
|
||||
let tool: ToolConfig | undefined
|
||||
|
||||
// Normalize tool ID to strip resource suffixes (e.g., workflow_executor_<uuid> -> workflow_executor)
|
||||
const normalizedToolId = normalizeToolId(toolId)
|
||||
|
||||
// If it's a custom tool, use the async version with workflowId
|
||||
if (toolId.startsWith('custom_')) {
|
||||
if (normalizedToolId.startsWith('custom_')) {
|
||||
const workflowId = params._context?.workflowId
|
||||
tool = await getToolAsync(toolId, workflowId)
|
||||
tool = await getToolAsync(normalizedToolId, workflowId)
|
||||
if (!tool) {
|
||||
logger.error(`[${requestId}] Custom tool not found: ${toolId}`)
|
||||
logger.error(`[${requestId}] Custom tool not found: ${normalizedToolId}`)
|
||||
}
|
||||
} else if (toolId.startsWith('mcp-')) {
|
||||
return await executeMcpTool(toolId, params, executionContext, requestId, startTimeISO)
|
||||
} else if (normalizedToolId.startsWith('mcp-')) {
|
||||
return await executeMcpTool(
|
||||
normalizedToolId,
|
||||
params,
|
||||
executionContext,
|
||||
requestId,
|
||||
startTimeISO
|
||||
)
|
||||
} else {
|
||||
// For built-in tools, use the synchronous version
|
||||
tool = getTool(toolId)
|
||||
tool = getTool(normalizedToolId)
|
||||
if (!tool) {
|
||||
logger.error(`[${requestId}] Built-in tool not found: ${toolId}`)
|
||||
logger.error(`[${requestId}] Built-in tool not found: ${normalizedToolId}`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user