import { useState, useEffect } from "react"; import { Button } from "@/components/ui/button"; import { Label } from "@/components/ui/label"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription, } from "@/components/ui/dialog"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Input } from "@/components/ui/input"; const BUILTIN_CONDITIONS = [ { value: "none", label: "None (always)" }, { value: "always", label: "Always" }, { value: "source_success", label: "Source Succeeded" }, { value: "source_failed", label: "Source Failed" }, { value: "has_response", label: "Has Response" }, { value: "contains", label: "Contains Keyword..." }, { value: "custom", label: "Custom..." }, ]; interface EdgeConditionDialogProps { open: boolean; onOpenChange: (open: boolean) => void; edgeId: string; currentCondition?: string | null; currentWeight?: number; onSave: (edgeId: string, condition: string, weight: number) => void; } export function EdgeConditionDialog({ open, onOpenChange, edgeId, currentCondition, currentWeight = 1.0, onSave, }: EdgeConditionDialogProps) { // Parse existing condition to detect contains:xxx format const parseCondition = (cond: string | null | undefined) => { if (!cond) return { selected: "none", keyword: "", custom: "" }; if (cond.startsWith("contains:")) { return { selected: "contains", keyword: cond.slice("contains:".length), custom: "" }; } const builtin = BUILTIN_CONDITIONS.find((c) => c.value === cond); if (builtin) return { selected: cond, keyword: "", custom: "" }; return { selected: "custom", keyword: "", custom: cond }; }; const parsed = parseCondition(currentCondition); const [selected, setSelected] = useState(parsed.selected); const [keyword, setKeyword] = useState(parsed.keyword); const [customCondition, setCustomCondition] = useState(parsed.custom); const [weight, setWeight] = useState(currentWeight); // Re-sync when the dialog opens with new props useEffect(() => { if (open) { const p = parseCondition(currentCondition); setSelected(p.selected); setKeyword(p.keyword); setCustomCondition(p.custom); setWeight(currentWeight); } }, [open, currentCondition, currentWeight]); const handleSave = () => { let condition = ""; if (selected === "custom") { condition = customCondition; } else if (selected === "contains") { condition = keyword ? `contains:${keyword}` : ""; } else if (selected === "none") { condition = ""; } else { condition = selected; } onSave(edgeId, condition, weight); onOpenChange(false); }; return ( Edge Configuration Set condition and weight for this edge transition.
{/* Condition */}
{selected === "contains" && (
setKeyword(e.target.value)} />

Edge is taken only if the source agent's response contains this keyword.

)} {selected === "custom" && (
setCustomCondition(e.target.value)} />
)} {/* Weight */}
{weight.toFixed(2)}
setWeight(parseFloat(e.target.value))} className="w-full accent-primary h-1.5" />

Higher weight = higher priority when scheduling. Edges below 0.1 may be pruned.

); }