"use client"; import { useState, useEffect } from "react"; interface OutputMapping { outputAs: "full" | "field" | "custom"; fieldName?: string; customPath?: string; } interface UniversalOutputSelectorProps { nodeId: string; nodeType: string; currentMapping?: OutputMapping; onUpdate: (mapping: OutputMapping) => void; } export default function UniversalOutputSelector({ nodeId, nodeType, currentMapping, onUpdate, }: UniversalOutputSelectorProps) { const [outputAs, setOutputAs] = useState<"full" | "field" | "custom">( currentMapping?.outputAs || "full" ); const [fieldName, setFieldName] = useState(currentMapping?.fieldName || "result"); const [customPath, setCustomPath] = useState(currentMapping?.customPath || ""); useEffect(() => { const timeoutId = setTimeout(() => { onUpdate({ outputAs, fieldName, customPath }); }, 300); return () => clearTimeout(timeoutId); }, [outputAs, fieldName, customPath, onUpdate]); const getDefaultFields = () => { switch (nodeType) { case 'agent': return ['message', 'text', 'response']; case 'mcp': case 'firecrawl': return ['markdown', 'html', 'json', 'results', 'urls']; case 'transform': return ['result', 'output', 'data']; case 'if-else': return ['condition', 'branch']; case 'while': return ['iterations', 'result']; case 'guardrails': return ['passed', 'sanitized', 'result']; case 'file-search': return ['files', 'matches']; default: return ['result', 'output']; } }; const defaultFields = getDefaultFields(); return (

Choose how downstream nodes access this node's output

{/* Full Output */} {/* Single Field */} {outputAs === 'field' && (
{fieldName === '__custom__' && ( { setCustomPath(e.target.value); setFieldName(e.target.value); }} placeholder="data.items[0].title" className="w-full px-10 py-6 bg-white border border-border-faint rounded-6 text-body-small text-accent-black font-mono focus:outline-none focus:border-heat-100 transition-colors" /> )}

Access as: state.variables.{nodeId}

)} {/* Custom Path */} {outputAs === 'custom' && (
setCustomPath(e.target.value)} placeholder="result.data.items[0].title" className="w-full px-10 py-6 bg-white border border-border-faint rounded-6 text-body-small text-accent-black font-mono focus:outline-none focus:border-heat-100 transition-colors" />

Supports dot notation and array indexing

)}
{/* Preview */}

Preview:

state.variables.{nodeId} {outputAs === 'field' && fieldName !== '__custom__' && ` → ${fieldName} only`} {outputAs === 'custom' && customPath && ` → ${customPath}`}
); }