diff --git a/frontend/src/lib/components/flows/content/AiAgentStepInputs.svelte b/frontend/src/lib/components/flows/content/AiAgentStepInputs.svelte index e23981d3ba..dea2ad6217 100644 --- a/frontend/src/lib/components/flows/content/AiAgentStepInputs.svelte +++ b/frontend/src/lib/components/flows/content/AiAgentStepInputs.svelte @@ -115,6 +115,9 @@ /** A linked agent's memory, once its config has loaded: whether it keeps managed memory decides * which history inputs the step offers. */ linkedMemory?: { memory: unknown } | undefined + /** Set when this agent's config lives in a resource, so `tools` arrives with it rather than + * with the step. */ + agentLinked?: boolean } let { @@ -145,7 +148,8 @@ onAddTool = undefined, onDeleteTool = undefined, toolPickerPortal = undefined, - linkedMemory = undefined + linkedMemory = undefined, + agentLinked = false }: Props = $props() let ws = $derived(workspace ?? $workspaceStore) @@ -226,9 +230,10 @@ }) }) - // No editor adds tools to an agent used as a tool, so its Tools section only shows the ones - // written into the flow by hand, read-only. - let toolsHidden = $derived(isAgentTool && tools.length === 0) + // No editor adds tools to an agent used as a tool, so an empty roster is all an inline one will + // ever have. Not a linked one: its tools arrive with the resource, so empty here means "not + // loaded" as often as "none", and `enabled_tools` is the step's to set either way. + let toolsHidden = $derived(isAgentTool && !agentLinked && tools.length === 0) let scopedFields = $derived( AGENT_FIELDS.filter( (spec) => diff --git a/frontend/src/lib/components/flows/content/FlowModuleComponent.svelte b/frontend/src/lib/components/flows/content/FlowModuleComponent.svelte index 192b6da28d..23ee88401d 100644 --- a/frontend/src/lib/components/flows/content/FlowModuleComponent.svelte +++ b/frontend/src/lib/components/flows/content/FlowModuleComponent.svelte @@ -199,6 +199,14 @@ let visibleSelected = $derived(selected === 'chat' && !canShowChatTab ? 'inputs' : selected) let runSettings: FlowRunSettings | undefined = $state() let agentLinked = $derived(flowModule.value.type === 'aiagent' && Boolean(flowModule.value.agent)) + // A tool row drills in by selecting that tool's graph node, and the graph draws tool nodes only + // for a step's own agent (`computeAIToolNodes`). An agent used as a tool has none, so its rows + // would offer a click that lands nowhere. + let onSelectToolInGraph = $derived( + isAgentTool + ? undefined + : (toolId: string) => selectionManager.selectId(toolId, { openPanel: true }) + ) let validCode = $state(true) let width = $state(1200) let testJob: Job | undefined = $state(undefined) @@ -1235,15 +1243,14 @@ workspace={opWs} visibilityKey={agentFieldsKey} linkedMemory={agentLinked ? linkedAgentMemory : undefined} + {agentLinked} tools={agentLinked ? getLinkedAgentTools( linkedToolsScope(opWs, $pathStore), linkedToolsModuleId ) : (flowModule.value.tools ?? [])} - onSelectTool={isAgentTool - ? undefined - : (toolId) => selectionManager.selectId(toolId, { openPanel: true })} + onSelectTool={onSelectToolInGraph} onAddTool={flowModuleSchemaMap ? (detail) => flowModuleSchemaMap?.addToolToAgent(flowModule.id, detail)