-
Notifications
You must be signed in to change notification settings - Fork 61
Feat: Implement job code diff preview and coordinated apply for AI assistant #4283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Implement backend support for coordinating job code apply operations across multiple collaborators, mirroring the workflow apply pattern. Backend changes: - Extract code field from Apollo responses in ai_assistant.ex - Support Apollo PR #259 'suggested_code' field with markdown fallback - Add channel handlers for start/done job code apply coordination - Broadcast apply state to prevent concurrent modifications Tests: - Add channel tests for job code apply coordination - Add end-to-end coordination test - Verify broadcasts include user metadata
Implement "Generated Job Code" display with APPLY/COPY buttons, coordinating apply operations across all collaborators. Frontend changes: - Add job code apply handler to AIAssistantPanelWrapper - Display "Generated Job Code" section in MessageList for job chat - Add store coordination functions for job code apply state - Disable save button during apply operation - Hide inline ADD buttons when message.code exists - Sync apply state across all connected users via broadcasts Coordination: - All users see "APPLYING..." state during apply - Apply buttons disabled for all users during operation - Graceful degradation when channel unavailable
Create foundational support for inline code diff previews: - Add MonacoRefContext to share Monaco ref without prop drilling - Implement showDiff/clearDiff methods in CollaborativeMonaco - Use dual-container pattern (standard editor + diff overlay) - Add dismiss button on diff overlay This infrastructure enables job chat to preview AI-suggested code changes directly in the Monaco editor.
Enable users to preview AI-suggested code changes: - Add PREVIEW button to job code messages (alongside APPLY/COPY) - Allow PREVIEW in readonly mode (removed isWriteDisabled check) - Auto-preview diffs when AI responds with code - Auto-dismiss diff when user changes workflow version - Track previewing state to prevent duplicate operations Addresses phase 2 enhancements from issue #3369.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4283 +/- ##
==========================================
- Coverage 89.29% 89.19% -0.10%
==========================================
Files 425 425
Lines 19899 19914 +15
==========================================
- Hits 17768 17762 -6
- Misses 2131 2152 +21 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
- Add 8 tests for extract_code_from_markdown/1 covering JavaScript/JS code block extraction, edge cases, and nil handling - Add 4 tests for job code apply coordination via Phoenix Channel covering user attribution (first_name vs email fallback), sequential coordination, and retry scenarios
- Add 11 tests for useAutoPreview hook covering mode filtering, session mount behavior, author filtering, duplicate prevention, and message selection - Add 11 tests for Monaco diff display (showDiff/clearDiff methods, dismiss button functionality) - Add monaco-editor mock to avoid 8MB+ package resolution issues - Configure vitest to alias monaco-editor to mock file
Auto-preview was broken for new conversations because the hook checked for any messages instead of assistant code messages. When a user sent the first message, the session had [userMessage], causing hasMessages to be true and preventing hasLoadedSession from being set. This meant the AI's code response would be skipped. Changes: - Check for assistant code messages instead of any messages on session initialization to correctly identify new vs old conversations - Add session ID tracking to properly reset state when switching between conversations - Add cleanup for diff editor on unmount to prevent memory leaks - Add test coverage for session switching behavior
The function was defined as private (defp) but tests were calling it as a public function, causing "undefined or private" errors. Changes: - Change defp to def to make the function public - Add @doc and @SPEC annotations - Update misleading comment that referenced waiting for Apollo PR #259 (that PR is already deployed; this is now a legitimate fallback) Fixes failing extract_code_from_markdown tests in AiAssistantTest.
Extract shared editor options (theme, fontSize, etc.) into a single baseEditorOptions object to ensure consistent formatting across both the collaborative editor and AI diff preview. Previously, the diff editor used 'vs-dark' theme with default font size while the main editor used custom 'default' theme with fontSize 14, causing visual inconsistencies.
Prevent users from accessing AI Assistant features when viewing older workflow versions (snapshots) to avoid confusion about which version they're modifying. Disables both UI buttons and keyboard shortcuts. Changes: - Add disabledMessage prop to AIButton component - Disable workflow-level AI button (Header) when viewing old snapshot - Disable job-level AI button (WorkflowEditor) when viewing pinned version - Disable Cmd+K keyboard shortcut when viewing pinned version - Show tooltip: "Switch to the latest version of this workflow to use the AI Assistant." Checks params['v'] to determine if viewing a pinned version vs latest.
Extend version change handling to automatically close the AI Assistant panel with animation when users switch to a pinned workflow version. Changes: - Close AI panel and clear session when switching to pinned version - Dismiss any active diff previews - Clear AI session messages and URL params (w-chat, j-chat) - Disable hover effects on AI buttons when disabled - Reuse isPinnedVersion to avoid duplicate version checks The panel remains closed when switching back to latest, requiring manual reopen. This prevents confusion about which version the AI is working with.
When closing the AI assistant panel or navigating back to the session list, clear any active diff preview in Monaco editor. This prevents the diff from persisting after the user has left the chat context. - Update handleClosePanel to clear diff before closing - Update handleShowSessions to clear diff before showing session list - Move both handlers after monacoRef and previewingMessageId declarations
Add applyingJobCodeMessageId to WorkflowStore state to track which AI message is being applied when job code changes are coordinated across collaborators. This ensures the "APPLYING..." indicator displays on the correct message for all users in a collaborative session, matching the existing workflow apply pattern. Changes: - Add applyingJobCodeMessageId field to Workflow.State interface - Store message_id in job_code_applying channel event handler - Clear message_id in job_code_applied channel event handler - Use stored message ID in AIAssistantPanelWrapper for display
|
looks great at first glance! added @josephjclark as a reviewer. |
|
I will try and get this reviewed tomorrow |
|
Thanks @josephjclark! I am going to do another self-review of the code today so that works well. This was quite a big bit of work over the Christmas period so want to look at it all with fresh eyes and perspective. |
Fixes two issues in AIAssistantPanelWrapper: 1. Replaces direct mutation of aiMode.context with immutable update pattern when attaching current job code to message context 2. Adds user-facing toast notification when Monaco editor ref is unavailable during code preview attempts The immutable update prevents potential bugs from mutating shared context objects. The notification provides helpful feedback instead of silent failure.
Addresses critical issues identified in self code review:
1. Fix memory leak in channel observer cleanup
- Add missing cleanup for job_code_applying/applied handlers
- Prevents handler accumulation on workflow switches
2. Fix Monaco ref race conditions (TOCTOU bugs)
- Capture monacoRef.current value before use in 5 locations
- Prevents crashes when ref becomes null between check and use
- Locations: handleClosePanel, handleShowSessions, version effect,
handlePreviewJobCode, handleApplyJobCode
These fixes prevent memory leaks during long sessions and eliminate
potential crashes during rapid view switching.
Reset diff editor model to null before disposing text models to prevent "TextModel got disposed before DiffEditorWidget model got reset" error. Monaco's diff editor requires its model references to be cleared before the underlying text models are disposed. Applied fix to clearDiff callback, showDiff cleanup, and unmount effect.
Replace ref mutation pattern with callback registration system for better architectural consistency. The previous implementation had AIAssistantPanelWrapper mutating a ref it didn't own, which violated ownership principles and made the data flow harder to trace. Changes: - MonacoRefContext now owns callback Set and provides registration function - AIAssistantPanelWrapper registers callback instead of mutating ref - CollaborativeMonaco calls context's handleDiffDismissed - Removed onDiffDismissed prop (replaced with context callback) - Pattern now matches CredentialModalContext for consistency Benefits: - Explicit ownership (context owns callbacks) - Automatic cleanup via useEffect return - Better testability and clearer data flow - Consistent with existing codebase patterns
Extract JSX to a named variable for better readability.
|
@josephjclark I did a bit of a self-review today. I was hoping to do a bit more, but I'm a bit under the weather still today. Check out the "Notes to reviewer" section for extra things I would appreciate an opinion on when reviewing. Also I am still very new to Elixir, so I may have missed something when making changes to backend code. |
taylordowns2000
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is great. thank you @lmac-1 .
midigofrank
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nicely done @lmac-1
Description
This PR adds a complete interactive code PREVIEW and APPLY workflow for AI-generated job code suggestions. Users can now preview proposed changes in a side-by-side Monaco diff editor, coordinate with collaborators in real-time, and apply code updates in one click.
I have also disabled AI assistant for both workflow and jobs when the version dropdown is != latest. This matches the behaviour of the old editor.
Key features:
PREVIEW button for Job code
APPLY button extended to Job code
Version management
Closes #3369
Validation steps
Basic PREVIEW/APPLY Flow
Multi-User Coordination
Version-Aware State
?v=in URL)Updating to historical version during AI chat
Edge Cases
Additional notes for the reviewer
MonacoRefContextbecause the dismiss button lives inCollaborativeMonaco(rendered byFullScreenIDE) butAIAssistantPanelWrapperneeds to be notified when clicked - they're in different tree branches. Open to simpler approaches.AI Usage
Please disclose how you've used AI in this work (it's cool, we just want to know!):
You can read more details in our Responsible AI Policy
Pre-submission checklist
:owner,:admin,:editor,:viewer)