From 018100a9a8055f1bb389598140e427f10bfb36c4 Mon Sep 17 00:00:00 2001 From: David Kaya Date: Sat, 21 Mar 2026 19:54:22 +0100 Subject: [PATCH] feat: fix settings header overlap, redesign pattern editor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix SettingsPanel and PatternEditor headers with pt-12 to clear the title bar overlay zone - Replace mode dropdown with visual mode selector cards showing icon, description, and inline flow diagrams for each pattern - Add flow pill diagrams (Single, Sequential, Concurrent, Handoff, Group Chat, Magentic) illustrating how agents interact - Add reasoning effort selector (Low/Medium/High/Maximum) to agent cards — previously not exposed in the editor - Improve agent cards with numbered badges and 3-column layout for name, model, and reasoning fields Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/renderer/components/PatternEditor.tsx | 311 ++++++++++++++++++---- src/renderer/components/SettingsPanel.tsx | 4 +- 2 files changed, 259 insertions(+), 56 deletions(-) diff --git a/src/renderer/components/PatternEditor.tsx b/src/renderer/components/PatternEditor.tsx index 318f5e3..e8fcbb0 100644 --- a/src/renderer/components/PatternEditor.tsx +++ b/src/renderer/components/PatternEditor.tsx @@ -1,6 +1,26 @@ -import { AlertCircle, CheckCircle, ChevronLeft, Plus, Trash2 } from 'lucide-react'; +import { useState, type ReactNode } from 'react'; +import { + AlertCircle, + ArrowLeftRight, + CheckCircle, + ChevronLeft, + GitFork, + ListOrdered, + Lock, + MessageSquare, + Plus, + Trash2, + Users, + type LucideIcon, +} from 'lucide-react'; -import { validatePatternDefinition, type OrchestrationMode, type PatternDefinition } from '@shared/domain/pattern'; +import { + validatePatternDefinition, + type OrchestrationMode, + type PatternDefinition, + type ReasoningEffort, + type PatternAgentDefinition, +} from '@shared/domain/pattern'; interface PatternEditorProps { pattern: PatternDefinition; @@ -11,7 +31,131 @@ interface PatternEditorProps { onBack: () => void; } -const modes: OrchestrationMode[] = ['single', 'sequential', 'concurrent', 'handoff', 'group-chat', 'magentic']; +const reasoningEfforts: { value: ReasoningEffort; label: string }[] = [ + { value: 'low', label: 'Low' }, + { value: 'medium', label: 'Medium' }, + { value: 'high', label: 'High' }, + { value: 'xhigh', label: 'Maximum' }, +]; + +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, @@ -53,7 +197,7 @@ function InputField({ export function PatternEditor({ pattern, isBuiltin, onChange, onDelete, onSave, onBack }: PatternEditorProps) { const issues = validatePatternDefinition(pattern); - function updateAgent(agentId: string, patch: Record) { + function updateAgent(agentId: string, patch: Partial) { onChange({ ...pattern, agents: pattern.agents.map((a) => (a.id === agentId ? { ...a, ...patch } : a)), @@ -62,8 +206,8 @@ export function PatternEditor({ pattern, isBuiltin, onChange, onDelete, onSave, return (
- {/* Header */} -
+ {/* Header — top padding clears the title bar overlay zone */} +
+ ); + })} +
+ + {/* Agents */}
@@ -186,6 +362,7 @@ export function PatternEditor({ pattern, isBuiltin, onChange, onDelete, onSave, description: '', instructions: '', model: 'gpt-5.4', + reasoningEffort: 'high', }, ], }) @@ -193,7 +370,7 @@ export function PatternEditor({ pattern, isBuiltin, onChange, onDelete, onSave, type="button" > - Add + Add agent
@@ -204,12 +381,17 @@ export function PatternEditor({ pattern, isBuiltin, onChange, onDelete, onSave, key={agent.id} >
- - Agent {index + 1} - +
+ + {index + 1} + + + {agent.name || 'Unnamed agent'} + +
{pattern.agents.length > 1 && ( )}
-
+ +
updateAgent(agent.id, { name: v })} @@ -234,22 +418,41 @@ export function PatternEditor({ pattern, isBuiltin, onChange, onDelete, onSave, placeholder="e.g. gpt-5.4" value={agent.model} /> -
- updateAgent(agent.id, { description: v })} - value={agent.description} - /> -
-
- updateAgent(agent.id, { instructions: v })} - placeholder="System prompt for this agent..." - value={agent.instructions} - /> -
+ +
+
+ updateAgent(agent.id, { description: v })} + placeholder="What this agent does..." + value={agent.description} + /> +
+
+ updateAgent(agent.id, { instructions: v })} + placeholder="System prompt for this agent..." + value={agent.instructions} + />
))} diff --git a/src/renderer/components/SettingsPanel.tsx b/src/renderer/components/SettingsPanel.tsx index bbcc572..a3c1fad 100644 --- a/src/renderer/components/SettingsPanel.tsx +++ b/src/renderer/components/SettingsPanel.tsx @@ -54,8 +54,8 @@ export function SettingsPanel({ return (
- {/* Header */} -
+ {/* Header — top padding clears the title bar overlay zone */} +

Settings