20 changed files with 53 additions and 627 deletions
@ -1,79 +0,0 @@ |
|||
"use client"; |
|||
|
|||
import { useEffect, useMemo } from "react"; |
|||
import { useUpdateNodeInternals } from "@xyflow/react"; |
|||
import { useWorkflowStore } from "@/store/workflowStore"; |
|||
import type { ModelInputDef, SelectedModel } from "@/types"; |
|||
import { modelSupportsReferenceMedia, type ReferenceMediaType } from "@/utils/generationInputSupport"; |
|||
|
|||
const DYNAMIC_INPUT_TYPES: readonly ModelInputDef["type"][] = ["image", "video", "audio", "text"]; |
|||
|
|||
function metadataSupportFlag(model: SelectedModel | undefined, inputType: ReferenceMediaType): boolean | null { |
|||
const metadata = model?.metadata; |
|||
if (!metadata) return null; |
|||
|
|||
if (inputType === "image" && typeof metadata.isSupportImages === "boolean") { |
|||
return metadata.isSupportImages; |
|||
} |
|||
if (inputType === "video" && typeof metadata.isSupportVideos === "boolean") { |
|||
return metadata.isSupportVideos; |
|||
} |
|||
if (inputType === "audio") { |
|||
if (typeof metadata.isSupportAudios === "boolean") return metadata.isSupportAudios; |
|||
if (typeof metadata.isSupportAudio === "boolean") return metadata.isSupportAudio; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
export function useDynamicModelInputEdges( |
|||
nodeId: string, |
|||
inputSchema: ModelInputDef[] | undefined, |
|||
selectedModel?: SelectedModel, |
|||
parameters?: Record<string, unknown> |
|||
): void { |
|||
const updateNodeInternals = useUpdateNodeInternals(); |
|||
const reconcileDynamicInputEdges = useWorkflowStore((state) => state.reconcileDynamicInputEdges); |
|||
|
|||
const schemaSignature = useMemo(() => { |
|||
if (!inputSchema || inputSchema.length === 0) return ""; |
|||
return inputSchema.map((input) => `${input.type}:${input.name}`).join("|"); |
|||
}, [inputSchema]); |
|||
|
|||
const supportSignature = useMemo(() => { |
|||
const metadata = selectedModel?.metadata; |
|||
const capabilitySignature = selectedModel?.capabilities?.join("|") ?? ""; |
|||
const parameterSignature = parameters ? Object.keys(parameters).sort().join("|") : ""; |
|||
return [ |
|||
selectedModel?.provider ?? "", |
|||
selectedModel?.modelId ?? "", |
|||
metadata?.isSupportImages, |
|||
metadata?.isSupportVideos, |
|||
metadata?.isSupportAudios, |
|||
metadata?.isSupportAudio, |
|||
capabilitySignature, |
|||
parameterSignature, |
|||
].join("|"); |
|||
}, [parameters, selectedModel]); |
|||
|
|||
const validInputTypes = useMemo(() => { |
|||
const hasSchema = Boolean(inputSchema?.length); |
|||
return DYNAMIC_INPUT_TYPES.filter((inputType) => { |
|||
if (inputType === "text") return true; |
|||
if (hasSchema && !inputSchema?.some((input) => input.type === inputType)) return false; |
|||
if (!selectedModel) return hasSchema; |
|||
|
|||
const mediaType = inputType as ReferenceMediaType; |
|||
const supportFlag = metadataSupportFlag(selectedModel, mediaType); |
|||
if (supportFlag === false) return false; |
|||
if (supportFlag === true) return true; |
|||
return modelSupportsReferenceMedia(selectedModel, mediaType, inputSchema, parameters); |
|||
}); |
|||
}, [inputSchema, parameters, selectedModel]); |
|||
|
|||
useEffect(() => { |
|||
updateNodeInternals(nodeId); |
|||
if (!schemaSignature && !selectedModel) return; |
|||
reconcileDynamicInputEdges?.(nodeId, validInputTypes); |
|||
}, [nodeId, reconcileDynamicInputEdges, schemaSignature, selectedModel, supportSignature, updateNodeInternals, validInputTypes]); |
|||
} |
|||
Loading…
Reference in new issue