- Introduce WorkflowAgentStage to manage agent stage configurations and enhance interaction with the workflow engine. - Implement WorkflowEdgeEvaluator for priority-aware edge evaluation, improving routing decisions based on conditions and user turns. - Update WorkflowBrain to handle user turns and routing more effectively, ensuring agents cannot have only one default path. - Enhance CallEndCoordinator to track speech events and manage call termination based on queued speech. - Add new models and output handling for workflow interactions, improving clarity and maintainability. - Update tests to validate the new routing logic and agent behavior under various scenarios.
117 lines
4.6 KiB
TypeScript
117 lines
4.6 KiB
TypeScript
"use client";
|
|
|
|
import { Plus } from "lucide-react";
|
|
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from "@/components/ui/dialog";
|
|
|
|
import { accentVar, type RuntimeNodeSpec } from "./specs";
|
|
|
|
export function AddNodeDialog({
|
|
open,
|
|
connectingFromSource,
|
|
specs,
|
|
canAdd,
|
|
onOpenChange,
|
|
onSelect,
|
|
}: {
|
|
open: boolean;
|
|
connectingFromSource: boolean;
|
|
specs: RuntimeNodeSpec[];
|
|
canAdd: (spec: RuntimeNodeSpec) => boolean;
|
|
onOpenChange: (open: boolean) => void;
|
|
onSelect: (spec: RuntimeNodeSpec) => void;
|
|
}) {
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent className="gap-0 overflow-hidden border border-hairline bg-card p-0 shadow-2xl sm:max-w-[500px]">
|
|
<DialogHeader className="relative overflow-hidden border-b border-hairline px-6 py-6 pr-16">
|
|
<div
|
|
aria-hidden
|
|
className="pointer-events-none absolute -right-14 -top-16 h-40 w-40 rounded-full opacity-40 blur-3xl"
|
|
style={{
|
|
background:
|
|
"radial-gradient(circle, var(--gradient-sky), transparent 68%)",
|
|
}}
|
|
/>
|
|
<div className="relative flex items-start gap-4">
|
|
<div className="flex h-11 w-11 shrink-0 items-center justify-center rounded-full bg-surface-strong text-foreground">
|
|
<Plus size={18} />
|
|
</div>
|
|
<div>
|
|
<div className="caption-label text-muted-soft">节点目录</div>
|
|
<DialogTitle className="font-display display-sm mt-1 text-ink">
|
|
添加节点
|
|
</DialogTitle>
|
|
<DialogDescription className="mt-2 leading-6">
|
|
{connectingFromSource
|
|
? "选择节点类型,将在当前节点下方创建并自动连接。"
|
|
: "选择节点类型并添加到画布中央,随后可编辑内容并建立连线。"}
|
|
</DialogDescription>
|
|
</div>
|
|
</div>
|
|
</DialogHeader>
|
|
|
|
<div className="flex max-h-[440px] flex-col gap-3 overflow-y-auto bg-canvas-soft/70 p-4">
|
|
{specs.length === 0 && (
|
|
<p className="rounded-2xl border border-dashed border-hairline-strong bg-card px-4 py-8 text-center text-sm text-muted-soft">
|
|
暂无可添加的节点类型。
|
|
</p>
|
|
)}
|
|
{specs.map((spec) => {
|
|
const Icon = spec.icon;
|
|
const allowed = canAdd(spec);
|
|
return (
|
|
<button
|
|
key={spec.type}
|
|
type="button"
|
|
disabled={!allowed}
|
|
className="group relative flex items-start gap-4 overflow-hidden rounded-2xl border border-hairline bg-card p-4 text-left shadow-sm transition-[border-color,box-shadow,transform] hover:-translate-y-0.5 hover:border-hairline-strong hover:shadow-md disabled:cursor-not-allowed disabled:opacity-55 disabled:hover:translate-y-0 disabled:hover:border-hairline disabled:hover:shadow-sm"
|
|
onClick={() => onSelect(spec)}
|
|
>
|
|
<span
|
|
aria-hidden
|
|
className="absolute left-5 right-5 top-0 h-px"
|
|
style={{
|
|
background: `linear-gradient(90deg, transparent, var(${accentVar(spec.accent)}), transparent)`,
|
|
}}
|
|
/>
|
|
<div
|
|
className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full text-foreground transition-transform group-hover:scale-105"
|
|
style={{
|
|
background: `color-mix(in srgb, var(${accentVar(spec.accent)}) 28%, var(--surface-strong))`,
|
|
}}
|
|
>
|
|
<Icon size={17} />
|
|
</div>
|
|
<div className="min-w-0 flex-1">
|
|
<div className="flex items-center gap-2 text-sm font-medium text-foreground">
|
|
<span>{spec.displayName}</span>
|
|
{!allowed && (
|
|
<span className="rounded-full bg-surface-strong px-2 py-0.5 text-[10px] font-normal text-muted-foreground">
|
|
已添加
|
|
</span>
|
|
)}
|
|
</div>
|
|
<div className="mt-1 text-xs leading-5 text-muted-foreground">
|
|
{spec.description}
|
|
</div>
|
|
</div>
|
|
<Plus
|
|
size={15}
|
|
className="mt-1 shrink-0 text-muted-soft transition-colors group-hover:text-foreground"
|
|
/>
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|