fix: address graph editor UX feedback

- Hide input handle on User Input nodes and output handle on User Output
  nodes (separate userInputNode/userOutputNode node types)
- Enable edge deletion in handoff mode only (Delete key or React Flow UI);
  only agent-to-agent edges are deletable, structural edges are protected
- Block all edge mutations (add/delete) in concurrent and group chat modes
- Add agent as disconnected node without auto-rebuilding the graph
- Add sequential reorder controls (↑↓) in the inspector panel with
  position/order swap and automatic edge rebuilding
- Replace circular group chat layout with vertical column to prevent
  bidirectional edge crossings
- Tighten handoff layout spacing so edges between triage and specialists
  don't overlap nodes
- Use smoothstep edge type for cleaner edge routing across all modes
- Add 6 new tests covering reorder, disconnected add, edge deletion rules,
  and node type assertions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-03-24 23:09:21 +01:00
co-authored by Copilot
parent 7d078faada
commit c6c8e79e9f
7 changed files with 392 additions and 55 deletions
+13 -14
View File
@@ -34,6 +34,7 @@ import {
type WorkspaceToolingSettings,
} from '@shared/domain/tooling';
import { addAgentNodeToGraph } from '@renderer/lib/patternGraph';
import { PatternGraphCanvas } from './pattern-graph/PatternGraphCanvas';
import { PatternGraphInspector } from './pattern-graph/PatternGraphInspector';
@@ -149,20 +150,16 @@ export function PatternEditor({
}
function addAgent() {
emitChange({
...pattern,
agents: [
...pattern.agents,
{
id: `agent-${crypto.randomUUID()}`,
name: `Agent ${pattern.agents.length + 1}`,
description: '',
instructions: '',
model: 'gpt-5.4',
reasoningEffort: 'high',
},
],
});
const newAgent: PatternAgentDefinition = {
id: `agent-${crypto.randomUUID()}`,
name: `Agent ${pattern.agents.length + 1}`,
description: '',
instructions: '',
model: 'gpt-5.4',
reasoningEffort: 'high',
};
const updatedGraph = addAgentNodeToGraph(graph, newAgent);
onChange({ ...pattern, agents: [...pattern.agents, newAgent], graph: updatedGraph });
}
function updateAgent(agentId: string, patch: Partial<PatternAgentDefinition>) {
@@ -474,9 +471,11 @@ export function PatternEditor({
availableModels={availableModels}
agents={pattern.agents}
graph={graph}
mode={pattern.mode}
selectedNodeId={selectedNodeId}
onAgentChange={updateAgent}
onAgentRemove={removeAgent}
onGraphChange={emitGraphChange}
/>
</div>
</div>