Refactor workflow agent and routing components for improved functionality
- 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.
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
"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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user