# 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 `` 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.