import { type ReactNode } from 'react'; import { AlertCircle, ArrowLeftRight, CheckCircle, ChevronDown, ChevronLeft, GitFork, ListOrdered, Lock, MessageSquare, Plus, ShieldCheck, Trash2, Users, type LucideIcon, } from 'lucide-react'; import type { ApprovalCheckpointKind, ApprovalPolicy } from '@shared/domain/approval'; import { findModel, getSupportedReasoningEfforts, resolveReasoningEffort, type ModelDefinition, } from '@shared/domain/models'; import { validatePatternDefinition, type OrchestrationMode, type PatternDefinition, type PatternAgentDefinition, } from '@shared/domain/pattern'; import { ModelSelect, ReasoningEffortSelect } from './AgentConfigFields'; interface PatternEditorProps { availableModels: ReadonlyArray; pattern: PatternDefinition; isBuiltin: boolean; onChange: (pattern: PatternDefinition) => void; onDelete?: () => void; onSave: () => void; onBack: () => void; } interface ModeInfo { icon: LucideIcon; label: string; description: string; } const modeInfo: Record = { single: { icon: MessageSquare, label: 'Single', description: 'Direct conversation with one agent', }, sequential: { icon: ListOrdered, label: 'Sequential', description: 'Agents process in order, each refining the result', }, concurrent: { icon: GitFork, label: 'Concurrent', description: 'Multiple agents respond in parallel', }, handoff: { icon: ArrowLeftRight, label: 'Handoff', description: 'Triage agent routes to specialists', }, 'group-chat': { icon: Users, label: 'Group Chat', description: 'Agents iterate in managed round-robin', }, magentic: { icon: Lock, label: 'Magentic', description: 'Not yet available in .NET', }, }; function FlowPill({ children, variant = 'agent' }: { children: ReactNode; variant?: 'user' | 'agent' }) { return ( {children} ); } function FlowArrow({ label }: { label?: string }) { return {label ?? '→'}; } function ModeFlowDiagram({ mode }: { mode: OrchestrationMode }) { switch (mode) { case 'single': return (
You Agent You
); case 'sequential': return (
A₁ A₂ A₃
); case 'concurrent': return (
You
A₁ A₂ A₃
You
); case 'handoff': return (
Triage S₁ S₂
); case 'group-chat': return (
A₁ A₂ A₃
); case 'magentic': return Coming soon; default: return null; } } function InputField({ label, value, onChange, multiline, placeholder, }: { label: string; value: string; onChange: (value: string) => void; multiline?: boolean; placeholder?: string; }) { const baseClasses = 'w-full rounded-lg border border-zinc-700 bg-zinc-900 px-3 py-2 text-[13px] text-zinc-100 placeholder-zinc-600 outline-none transition focus:border-indigo-500/50'; return (