feat: connections improvements

This commit is contained in:
2026-03-11 23:05:01 +01:00
parent 3ef30bd58c
commit e79821bd81
6 changed files with 180 additions and 21 deletions

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useContext, useMemo, useState } from 'react'
import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react'
import {
AbstractNodeProps,
createAbstractNodeComponent,
@@ -26,6 +26,8 @@ export type AgentNodeData = {
outputMarkdown?: string
error?: string
loading?: boolean
/** Signature of inputs (sourceIds + config contents) from the last successful run. Used to show on-hold when current inputs differ. */
lastRunSourceSignature?: string
}
type Props = AbstractNodeProps<AgentNodeData>
@@ -57,6 +59,8 @@ function AgentNodeComponent({ id, data, width, height, selected }: Props) {
const setFullscreenNodeId = flowContext?.setFullscreenNodeId
const startConnectionPathUpdate = flowContext?.startConnectionPathUpdate
const endConnectionPathUpdate = flowContext?.endConnectionPathUpdate
const addConnectionPathPausedNode = flowContext?.addConnectionPathPausedNode
const removeConnectionPathPausedNode = flowContext?.removeConnectionPathPausedNode
const supportsFullscreen = getNodeType('agent')?.supportsFullscreen
const { nodes, sourceIds, updateData } = useAbstractNode<AgentNodeData>(id, data ?? {})
const { aiConnection } = usePlatform()
@@ -79,6 +83,16 @@ function AgentNodeComponent({ id, data, width, height, selected }: Props) {
})
}, [sourceIds, nodes])
const sourceSignature = useMemo(() => {
const configContents = sourceIds
.filter((sid) => {
const n = nodes.find((n: { id: string }) => n.id === sid)
return (n as { type?: string } | undefined)?.type === 'config'
})
.map((sid) => getConfigContent((nodes.find((n: { id: string }) => n.id === sid)?.data ?? undefined) as Record<string, unknown> | undefined))
return JSON.stringify({ sourceIds: sourceIds.slice().sort(), configContents })
}, [sourceIds, nodes])
const runAgent = useCallback(async () => {
const configContents = sourceIds
.filter((sid) => {
@@ -89,6 +103,7 @@ function AgentNodeComponent({ id, data, width, height, selected }: Props) {
const prompt = configContents.length > 0 ? configContents.join('\n\n---\n\n') : 'No prompt provided. Please describe what you want in structured markdown.'
const contextNodes = sourceIds.map((sid) => ({ id: sid, content: serializeNodeForContext(nodes, sid) }))
removeConnectionPathPausedNode?.(id)
updateData({ error: undefined, loading: true })
startConnectionPathUpdate?.(id)
setRunning(true)
@@ -114,7 +129,12 @@ function AgentNodeComponent({ id, data, width, height, selected }: Props) {
return
}
const markdown = (json as { markdown?: string }).markdown ?? ''
updateData({ loading: false, error: undefined, outputMarkdown: markdown })
updateData({
loading: false,
error: undefined,
outputMarkdown: markdown,
lastRunSourceSignature: sourceSignature,
})
endConnectionPathUpdate?.(id)
} catch (err: unknown) {
updateData({
@@ -126,13 +146,26 @@ function AgentNodeComponent({ id, data, width, height, selected }: Props) {
} finally {
setRunning(false)
}
}, [sourceIds, nodes, contextText, updateData, aiConnection])
}, [sourceIds, nodes, contextText, sourceSignature, updateData, aiConnection, removeConnectionPathPausedNode, startConnectionPathUpdate, endConnectionPathUpdate])
const onContextChange = useCallback(
(e: React.ChangeEvent<HTMLTextAreaElement>) => updateData({ context: e.target.value }),
[updateData]
)
const pathNodeIds = flowContext?.connectionPathNodeIds
const triggerNodeIds = flowContext?.connectionPathTriggerNodeIds ?? []
const lastRunSourceSignature = data?.lastRunSourceSignature
const hasPendingInputs =
pathNodeIds?.has(id) &&
triggerNodeIds.length > 0 &&
!loading &&
sourceSignature !== lastRunSourceSignature
useEffect(() => {
if (hasPendingInputs) addConnectionPathPausedNode?.(id)
else removeConnectionPathPausedNode?.(id)
}, [id, hasPendingInputs, addConnectionPathPausedNode, removeConnectionPathPausedNode])
return (
<BaseNode
className="min-w-[360px] min-h-[320px]"