feat: Flow Transfer, Procedural Assist & UI Design System #97
361
docs/plans/2026-03-06-editor-embedded-flow-assist-design.md
Normal file
361
docs/plans/2026-03-06-editor-embedded-flow-assist-design.md
Normal file
@@ -0,0 +1,361 @@
|
||||
# Editor-Embedded Flow Assist - Design Document
|
||||
|
||||
> **Date:** 2026-03-06
|
||||
> **Status:** Approved
|
||||
> **Replaces:** Standalone AI Chat Builder (`/ai/chat`)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Replace the standalone `/ai/chat` page with a context-aware AI side panel embedded directly in each editor (Troubleshooting + Procedural). The panel knows which node/step is focused, supports targeted and open-ended actions, and applies changes via a tiered suggestion system. Knowledge integration and variable inference are phased features built on the same panel architecture.
|
||||
|
||||
**Key Principles:**
|
||||
- Context-aware: panel knows the full tree/step structure + focal node
|
||||
- Targeted actions auto-apply; open-ended suggestions require acceptance
|
||||
- Output-based thresholds determine suggestion UX
|
||||
- Model routing is config-driven, not hardcoded
|
||||
- Chat history persists per-flow, per-user
|
||||
|
||||
---
|
||||
|
||||
## Panel Layout & Behavior
|
||||
|
||||
### Dimensions & Styling
|
||||
- **Width:** 320px fixed, right side
|
||||
- **Styling:** Glassmorphism (`.glass-card-static` bg, backdrop blur, `border-l border-border`)
|
||||
- **Z-index:** Same layer as node editor panel (not overlay)
|
||||
|
||||
### Single-Panel Rule
|
||||
- **Tree editor:** AI panel occupies the right panel slot, closing the node editor panel. When AI panel closes, if a node was previously being edited, the node editor panel reopens for that node.
|
||||
- **Procedural editor:** AI panel slides in from right, narrowing the step list (step list takes `flex-1`). No existing panel to replace.
|
||||
|
||||
### Top Section: Context Summary
|
||||
- **Node/step selected:** Read-only summary showing type, title, question/description of the focused item.
|
||||
- **No selection:** Flow summary showing name, node/step count, flow type.
|
||||
- Switching selection updates the summary live.
|
||||
|
||||
### Tabs
|
||||
- **Chat** — conversation + inline suggestions
|
||||
- **Suggestions** — audit trail of all AI-applied changes to this flow (accepted, dismissed, pending)
|
||||
|
||||
### Visibility
|
||||
- Hidden by default
|
||||
- Auto-opens on: AI-assisted flow creation, right-click AI action, toolbar toggle
|
||||
- Auto-contextual: opens with focal node already set when triggered via context menu
|
||||
|
||||
---
|
||||
|
||||
## Entry Points
|
||||
|
||||
### 1. Create Flow Dropdown (AI-Assisted)
|
||||
- "Blank" or "AI-assisted" option per flow type (Troubleshooting, Project, Maintenance)
|
||||
- **AI-assisted** shows a simple prompt dialog modal:
|
||||
- Text area: "Describe the flow you want to build"
|
||||
- Flow type already known from dropdown selection
|
||||
- Loading state during generation
|
||||
- On failure: error message + retry button (stays in dialog)
|
||||
- On success: creates tree via API, navigates to editor with AI panel auto-opened and generation chat history loaded
|
||||
- No multi-phase interview, no preview — just prompt and go
|
||||
|
||||
### 2. Right-Click Context Menu
|
||||
- New `<ContextMenu>` component (no existing context menus in either editor)
|
||||
- Positioned absolutely at right-click point
|
||||
- Closes on click-away, Escape, or action selection
|
||||
- **Tree editor items:** Generate branch, Add decision/action/solution, Explain node, Find known fixes, Delete
|
||||
- **Procedural editor items:** Generate steps after, Add verification step, Expand step, Generate section, Delete
|
||||
- Selecting an AI action sets the focal node/step and opens the AI panel
|
||||
|
||||
### 3. Toolbar Toggle
|
||||
- "AI Assist" button in editor toolbar to manually open/close the panel
|
||||
|
||||
### 4. Existing Flows
|
||||
- AI panel works on any flow — new or existing, AI-created or manually built
|
||||
- No restriction to AI-created flows
|
||||
|
||||
---
|
||||
|
||||
## Suggestion & Apply System
|
||||
|
||||
### Ghost Node/Step Mechanics
|
||||
|
||||
Ghost nodes/steps are added to `treeStructure`/steps array with a `_suggestion: true` flag:
|
||||
- Canvas/step list renders them normally (auto-layout works) but with **dashed borders + reduced opacity**
|
||||
- Zundo temporal store **paused** while suggestions are pending
|
||||
- On **accept**: remove `_suggestion` flag, unpause zundo (creates one clean undo point)
|
||||
- On **dismiss**: remove ghost nodes from structure, unpause zundo (no undo point created)
|
||||
- Ghost nodes participate in auto-layout and connection drawing but are visually distinct
|
||||
|
||||
### Addition vs Modification
|
||||
|
||||
| Change Type | Visual Treatment |
|
||||
|---|---|
|
||||
| **New nodes/steps** | Ghost nodes: dashed borders, reduced opacity |
|
||||
| **Modified existing nodes** | Subtle highlight + badge showing what changed |
|
||||
| **Modified selected node** | Before/after shown in chat message with Apply button (not inline ghost) |
|
||||
|
||||
### Output-Based Threshold
|
||||
|
||||
| Output Size | Behavior |
|
||||
|---|---|
|
||||
| **1 node/step** | Auto-apply + toast notification with undo link |
|
||||
| **2-4 nodes/steps** | Individual ghost suggestions + "Accept All" shortcut button |
|
||||
| **5+ nodes/steps** | Ghost suggestions grouped by branch (tree) or section (procedural) with "Accept Branch"/"Accept Section" and "Accept All" controls + summary card in panel |
|
||||
|
||||
All changes (accepted or dismissed) logged in the Suggestions tab as an audit trail.
|
||||
|
||||
---
|
||||
|
||||
## Backend Action Types
|
||||
|
||||
Each message to the AI includes an `action_type` that determines prompt construction, response schema, and model routing:
|
||||
|
||||
| Action Type | Description | Model Tier | Response Format |
|
||||
|---|---|---|---|
|
||||
| `generate_full` | Initial skeleton from prompt dialog | standard | Full tree structure or step array |
|
||||
| `generate_branch` | Generate children for a specific node | standard | Subtree delta (node + children) |
|
||||
| `modify_node` | Update a specific node's content | fast | Single node delta (before/after) |
|
||||
| `add_steps` | Add steps after a specific step | standard | Step array delta |
|
||||
| `quick_action` | Single-node operations (explain, expand) | fast | Single node delta or text response |
|
||||
| `open_chat` | General conversation about the flow | standard | Text + optional delta |
|
||||
| `variable_inference` | Detect implicit variables in step content | fast | Variable suggestions |
|
||||
|
||||
### Prompt Construction
|
||||
|
||||
Each action type gets a tailored system prompt:
|
||||
- **Full tree context** always included (so AI understands the complete flow)
|
||||
- **Focal node** highlighted when present (the specific node/step being acted on)
|
||||
- **Action instruction** describes what the AI should return
|
||||
- **Response schema** constrains output format (full tree, subtree delta, single node, text)
|
||||
|
||||
### Delta Response Format
|
||||
|
||||
For partial updates, the AI returns a delta object:
|
||||
```json
|
||||
{
|
||||
"action": "add" | "modify" | "delete",
|
||||
"target_node_id": "node-to-modify-or-insert-after",
|
||||
"nodes": [{ /* node objects */ }],
|
||||
"explanation": "What was changed and why"
|
||||
}
|
||||
```
|
||||
|
||||
The frontend applies the delta to the tree structure and renders ghost nodes as appropriate.
|
||||
|
||||
---
|
||||
|
||||
## Model Routing (Config-Driven)
|
||||
|
||||
### Configuration
|
||||
|
||||
```python
|
||||
# backend/app/core/config.py
|
||||
AI_MODEL_TIERS = {
|
||||
"fast": "claude-haiku-4-5-20251001",
|
||||
"standard": "claude-sonnet-4-6-20250514",
|
||||
}
|
||||
|
||||
ACTION_MODEL_MAP = {
|
||||
"generate_full": "standard",
|
||||
"generate_branch": "standard",
|
||||
"modify_node": "fast",
|
||||
"add_steps": "standard",
|
||||
"quick_action": "fast",
|
||||
"open_chat": "standard",
|
||||
"variable_inference": "fast",
|
||||
}
|
||||
```
|
||||
|
||||
### Routing Logic
|
||||
|
||||
1. Message endpoint receives `action_type` parameter
|
||||
2. Look up tier from `ACTION_MODEL_MAP`
|
||||
3. Resolve model name from `AI_MODEL_TIERS`
|
||||
4. Pass to Anthropic API call
|
||||
|
||||
Both tiers can map to the same model initially. Changing model assignment is a config change, not a code change.
|
||||
|
||||
---
|
||||
|
||||
## Knowledge Integration (Phased)
|
||||
|
||||
### Phase 1 (Initial Release)
|
||||
- Uses existing Microsoft Learn MCP server
|
||||
- AI can cite KB articles, known issues, and official fix procedures in chat responses
|
||||
- Citations rendered inline as collapsible cards with source URL and title
|
||||
- AI response marker: `[KNOWLEDGE]{"title": "...", "url": "...", "excerpt": "..."}[/KNOWLEDGE]`
|
||||
|
||||
### Phase 2 (Future)
|
||||
- Additional vendor documentation sources
|
||||
- Community knowledge bases
|
||||
- Proactive suggestions ("Microsoft released KB5034441 addressing this scenario")
|
||||
|
||||
---
|
||||
|
||||
## Chat Persistence
|
||||
|
||||
### Session Model
|
||||
- `ai_chat_session` model extended with:
|
||||
- `tree_id` FK (which flow this session belongs to)
|
||||
- `archived_at` timestamp (null = active)
|
||||
- Per-flow, per-user sessions: multiple engineers on the same flow get separate chat histories
|
||||
- Session loads on panel open if one exists for this flow + user
|
||||
|
||||
### Suggestions Audit Trail
|
||||
New `ai_suggestion` table:
|
||||
|
||||
| Column | Type | Description |
|
||||
|---|---|---|
|
||||
| `id` | UUID | Primary key |
|
||||
| `tree_id` | UUID FK | Which flow |
|
||||
| `user_id` | UUID FK | Who triggered |
|
||||
| `session_id` | UUID FK | Which chat session |
|
||||
| `action_type` | String | Action that generated this suggestion |
|
||||
| `target_node_id` | String | Node/step acted on (nullable) |
|
||||
| `changes_json` | JSONB | Before/after snapshot |
|
||||
| `status` | Enum | `pending`, `accepted`, `dismissed` |
|
||||
| `created_at` | DateTime(tz) | When suggested |
|
||||
| `resolved_at` | DateTime(tz) | When accepted/dismissed (nullable) |
|
||||
|
||||
### Auto-Archive
|
||||
- APScheduler task runs daily
|
||||
- Archives sessions with no activity for 30 days (`archived_at = now()`)
|
||||
- Archived sessions viewable in Suggestions tab but not resumable for chat
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting Editor Integration
|
||||
|
||||
### Panel Context
|
||||
- Full tree structure included in AI context
|
||||
- Focal node (when selected/right-clicked) highlighted in context
|
||||
- Node summary at panel top shows: type icon, node ID, question/title, option count
|
||||
|
||||
### Context Menu Actions
|
||||
| Action | Description | Model Tier |
|
||||
|---|---|---|
|
||||
| Generate branch | Create child nodes from this decision | standard |
|
||||
| Add decision node | Add a decision child | fast |
|
||||
| Add action node | Add an action child | fast |
|
||||
| Add solution node | Add a solution child | fast |
|
||||
| Explain node | AI explains what this node does | fast |
|
||||
| Find known fixes | Search knowledge sources for this scenario | standard |
|
||||
|
||||
### Ghost Node Rendering
|
||||
- Dashed `border-dashed border-primary/40` borders
|
||||
- `opacity-60` on the node card
|
||||
- Connection lines drawn with dashed stroke
|
||||
- Accept/dismiss buttons overlaid on each ghost node
|
||||
- "Accept All" button in the panel when 2+ ghost nodes
|
||||
|
||||
---
|
||||
|
||||
## Procedural Editor Integration
|
||||
|
||||
### Panel Context
|
||||
- Full step list included in AI context
|
||||
- Focal step (when selected/right-clicked) highlighted in context
|
||||
- Step summary at panel top shows: step number, type badge, title, content type
|
||||
|
||||
### Context Menu Actions
|
||||
| Action | Description | Model Tier |
|
||||
|---|---|---|
|
||||
| Generate steps after | Add steps following this one | standard |
|
||||
| Add verification step | Insert a verification step | fast |
|
||||
| Expand step | Break this step into substeps | standard |
|
||||
| Generate section | Create a section header + steps | standard |
|
||||
|
||||
### Ghost Step Rendering
|
||||
- Dashed left border (`border-l-2 border-dashed border-primary/40`)
|
||||
- `opacity-60` background
|
||||
- Accept/dismiss buttons on each ghost step
|
||||
- Grouped by section when 5+ suggestions
|
||||
|
||||
### Intake Variable Detection (Three Tiers)
|
||||
|
||||
| Tier | Trigger | Timing | Model Tier |
|
||||
|---|---|---|---|
|
||||
| **Explicit** | `[VAR:name]` syntax in step content | Immediate on content save | None (regex match) |
|
||||
| **Inference** | Natural language suggests variable ("check the customer's server") | Debounced on step save/blur | fast |
|
||||
| **Cross-step** | Same implicit variable in 2+ steps | On panel open + when steps modified | fast |
|
||||
|
||||
**Behavior:**
|
||||
- Explicit: immediate inline suggestion card in panel ("Add `server_name` to intake form?")
|
||||
- Inference: non-blocking suggestion in panel, lower confidence indicator
|
||||
- Cross-step: promoted suggestion with gap flag ("Variable `server_name` used in steps 3, 7, 12 but not captured in intake form")
|
||||
- Results cached per-session until step content changes
|
||||
|
||||
---
|
||||
|
||||
## What Gets Removed
|
||||
|
||||
| Item | Location |
|
||||
|---|---|
|
||||
| `AIChatBuilderPage.tsx` | `frontend/src/pages/` |
|
||||
| `aiChatStore.ts` | `frontend/src/store/` |
|
||||
| `ai-chat/` component directory | `frontend/src/components/` |
|
||||
| `AIFlowBuilderModal` | `frontend/src/components/` |
|
||||
| `/ai/chat` route | `frontend/src/router.tsx` |
|
||||
| Flow type selection routing | URL params `?type=...` |
|
||||
|
||||
---
|
||||
|
||||
## What Gets Repurposed
|
||||
|
||||
| Item | Changes |
|
||||
|---|---|
|
||||
| `ai_chat_service.py` | Action-type dispatch, partial generation prompts, model routing, focal node context |
|
||||
| `ai_tree_validator.py` | Validates AI-generated fragments (subtree, step batch) in addition to full trees |
|
||||
| `ai_chat_session` model | Extended with `tree_id` FK, `archived_at` timestamp |
|
||||
| AI chat endpoints | Tree-scoped sessions, `action_type` parameter, model tier routing |
|
||||
|
||||
---
|
||||
|
||||
## What Gets Built (New)
|
||||
|
||||
| Item | Description |
|
||||
|---|---|
|
||||
| `EditorAIPanel` component | Shared panel with Chat + Suggestions tabs, node summary, input |
|
||||
| `ContextMenu` component | Shared right-click menu for nodes and steps |
|
||||
| `useEditorAI` hook | Panel state, focal node, suggestion management, ghost node lifecycle |
|
||||
| Prompt dialog modal | Simple "describe your flow" modal for AI-assisted create |
|
||||
| `ai_suggestion` DB model | Audit trail table + Alembic migration |
|
||||
| Ghost node CSS | Dashed borders, reduced opacity, accept/dismiss overlays |
|
||||
| Model tier config | `AI_MODEL_TIERS` + `ACTION_MODEL_MAP` in `config.py` |
|
||||
| APScheduler archive task | Daily job to archive stale sessions |
|
||||
|
||||
---
|
||||
|
||||
## What Gets Modified
|
||||
|
||||
| Item | Changes |
|
||||
|---|---|
|
||||
| `TreeEditorPage` | Right panel slot for AI, context menu handler, ghost node support |
|
||||
| `TreeCanvas` / `TreeCanvasNode` | Ghost node rendering (dashed borders, overlays) |
|
||||
| `ProceduralEditorPage` | Flex layout for AI panel, context menu on steps |
|
||||
| `StepList` / `StepEditor` | Ghost step rendering |
|
||||
| `treeEditorStore` | Ghost node state slice, zundo pause/resume, orphan bug fix |
|
||||
| `proceduralEditorStore` | Ghost step state slice |
|
||||
| `ai_chat_service.py` | Action-type dispatch, delta response format, model routing |
|
||||
| `ai_chat_session` model | `tree_id` FK, `archived_at` |
|
||||
| `config.py` | Model tier configuration |
|
||||
| `CreateFlowDropdown` | AI-assisted option + prompt dialog trigger |
|
||||
| `router.tsx` | Remove `/ai/chat` route |
|
||||
|
||||
---
|
||||
|
||||
## Bug Fix (Included)
|
||||
|
||||
**File:** `frontend/src/store/treeEditorStore.ts` line 858
|
||||
|
||||
**Current code:**
|
||||
```typescript
|
||||
if (id !== 'root' && !referencedIds.has(id)) {
|
||||
```
|
||||
|
||||
**Fixed code:**
|
||||
```typescript
|
||||
if (id !== state.treeStructure?.id && !referencedIds.has(id)) {
|
||||
```
|
||||
|
||||
**Root cause:** Orphan check hardcodes `'root'` as the expected root node ID. AI-generated trees use descriptive IDs (e.g., `"verify-account-exists"`). Since the root is never referenced by any other node's `next_node_id`, it gets flagged as orphaned. This is a false positive.
|
||||
Reference in New Issue
Block a user