Repository navigation
feat(frontend): add AI workflow fixer with LLM-powered diff panel #8637
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
Open
pedroreyesalvarado
wants to merge
45
commits into
apache:main
Choose a base branch
from
pedroreyesalvarado:feat/ai-workflow-fixer
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+2,725
−28
Open
Changes from 27 commits
Commits
Show all changes
45 commits
Select commit
Hold shift + click to select a range
cd625e8
feat(frontend): add AI workflow fixer with LLM-powered diff panel
a79eebf
fix(demo-workflows): add required defaultEnv to Python UDF operators
c286bcc
fix(frontend): register the AI fix tab for Python UDF console errors
0eb0a3f
fix(frontend): guard property fixes against a stale suggestion
19d21b6
fix(frontend): don't report a re-run the deployment will refuse
2f8bbb7
fix(frontend): show the AI fix tab when the traceback arrives
b8926d2
fix(frontend): tear down the AI fix tab when the error clears
56889cc
docs(demo-workflows): add the pipeline demo and document the TextInpu…
e749a0c
docs(examples): move the AI fix demo workflows out of the repo root
931a977
fix(frontend): scope the AI fix frame to its own operator
c6157cb
fix(frontend): address the second review round
39185db
fix(frontend): drop a stale analysis and fix a lint error
81e7d26
fix(frontend): keep operator credentials out of the AI fix prompt
383d3a0
fix(frontend): stop the console stream rerendering the whole panel
587b7b4
fix(frontend): guard the apply path and classify on the real exception
45f3f6e
fix(frontend): close the four remaining panel-state findings
a251a87
fix(frontend): send every input port's schema, not just port 0
b784df2
fix(frontend): make applying a fix honest about what it does
8fc6575
refactor(frontend): drop three write-only fields from the panel state
8844081
Merge remote-tracking branch 'origin/main' into feat/ai-workflow-fixer
f48df00
refactor(frontend): ask ExecuteWorkflowService whether the run started
bd5a964
fix(frontend): stop the panel naming a refusal reason it no longer knows
e7c0d7b
fix(frontend): stop a late analysis repainting a cleared panel
05772fa
Merge remote-tracking branch 'origin/main' into feat/ai-workflow-fixer
b622cb6
Merge remote-tracking branch 'origin/main' into feat/ai-workflow-fixer
55f5ccd
fix(frontend): bind a suggestion to its workflow, and make retry work
88b22d9
fix(frontend): scope the frame by workflow, and stop an apply reporti…
a465fe5
Merge remote-tracking branch 'origin/main' into feat/ai-workflow-fixer
7ee6339
fix(frontend): keep credentials out of the diff, read JVM errors, dro…
e8798c9
fix(frontend): refuse what cannot be applied, stop guessing indentation
e4e474f
fix(frontend): refuse a bad field name before it reaches the diff
2057c03
docs(frontend): put the execution-state comments back on their own sets
711b328
fix(frontend): count the snippet at Apply, not just find it
68c65b1
fix(frontend): key the frame tabs by their config, not by their name
03cd234
fix(frontend): validate the fix before the kill, not only after it
114b582
fix(frontend): classify on the exception the source already separated
e35d097
fix(frontend): ask for whole indented lines instead of guessing inden…
b3f3606
fix(frontend): decide the AI Fix tab from the map, not a remembered key
26462fa
Merge remote-tracking branch 'origin/main' into feat/ai-workflow-fixer
10d3775
fix(frontend): require the snippet to end a line, and drop a check th…
0935e66
refactor(frontend): keep only the fixes this panel can actually write
7873a6b
refactor(frontend): drop a parameter the deleted branch was the only …
d4b8068
fix(frontend): stop sending operator configuration, and stop refusing…
bec7f92
Merge remote-tracking branch 'origin/main' into feat/ai-workflow-fixer
7d3ccda
feat(config): read the AI fix model from configuration
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
132 changes: 132 additions & 0 deletions
132
frontend/src/app/workspace/component/result-panel/ai-fix/ai-fix-frame.component.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,132 @@ | ||
| <!-- | ||
| Licensed to the Apache Software Foundation (ASF) under one | ||
| or more contributor license agreements. See the NOTICE file | ||
| distributed with this work for additional information | ||
| regarding copyright ownership. The ASF licenses this file | ||
| to you under the Apache License, Version 2.0 (the | ||
| "License"); you may not use this file except in compliance | ||
| with the License. You may obtain a copy of the License at | ||
|
|
||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, | ||
| software distributed under the License is distributed on an | ||
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| KIND, either express or implied. See the License for the | ||
| specific language governing permissions and limitations | ||
| under the License. | ||
| --> | ||
|
|
||
| <ng-container *ngIf="state$ | async as state"> | ||
| <div | ||
| class="ai-fix-status" | ||
| *ngIf="state.status === 'analyzing' || state.status === 'applying'"> | ||
| <nz-spin nzSize="small"></nz-spin> | ||
| <span>{{ state.status === "analyzing" ? "Analyzing error with AI..." : "Applying fix..." }}</span> | ||
| </div> | ||
|
|
||
| <!-- Nothing has been analysed yet (or the user discarded the last suggestion). --> | ||
| <div | ||
| class="ai-fix-start" | ||
| *ngIf=" | ||
| state.status === 'idle' || | ||
| state.status === 'applied' || | ||
| state.status === 'applied_without_run' || | ||
| state.status === 'error' || | ||
| (state.status === 'ready' && state.errorType === 'unsupported') | ||
| "> | ||
| <button | ||
| nz-button | ||
| nzType="primary" | ||
| class="ai-fix-analyze" | ||
| [disabled]="!operatorId" | ||
| (click)="onAnalyze()"> | ||
| <span | ||
| nz-icon | ||
| nzType="robot"></span> | ||
| Analyze with AI | ||
| </button> | ||
| </div> | ||
|
|
||
| <nz-alert | ||
| *ngIf="state.status === 'ready' && state.errorType === 'unsupported'" | ||
| nzType="info" | ||
| [nzMessage]="unsupportedMessage"></nz-alert> | ||
|
|
||
| <nz-alert | ||
| *ngIf="state.status === 'applied'" | ||
| nzType="success" | ||
| nzMessage="Fix applied — workflow re-running..."></nz-alert> | ||
|
|
||
| <nz-alert | ||
| *ngIf="state.status === 'applied_without_run'" | ||
| nzType="warning" | ||
| nzMessage="Fix applied, but the re-run was refused. The reason is in the notification; run again once it is resolved."></nz-alert> | ||
|
|
||
| <nz-alert | ||
| *ngIf="state.status === 'apply_failed'" | ||
| nzType="warning" | ||
| [nzMessage]="'Could not apply: ' + state.applyError + '. Review the diff and try again.'"></nz-alert> | ||
|
|
||
| <nz-alert | ||
| *ngIf="state.status === 'error'" | ||
| nzType="error" | ||
| nzMessage="The AI could not suggest a fix for this error. Check the console for details."></nz-alert> | ||
|
|
||
| <ng-container *ngIf="(state.status === 'ready' || state.status === 'apply_failed') && state.suggestedFix as fix"> | ||
| <div class="ai-fix-section-title">🔍 Root cause</div> | ||
| <p class="ai-fix-explanation">{{ fix.explanation }}</p> | ||
|
|
||
| <div class="ai-fix-section-title"> | ||
| 📝 Proposed fix | ||
| <nz-tag [nzColor]="confidenceColor(fix.confidence)">{{ fix.confidence }} confidence</nz-tag> | ||
| <nz-tag | ||
| *ngIf="fix.occurrences && fix.occurrences > 1" | ||
| nzColor="orange" | ||
| >changes {{ fix.occurrences }} places</nz-tag | ||
| > | ||
| </div> | ||
|
|
||
| <div | ||
| class="ai-fix-field" | ||
| *ngIf="fix.type === 'property_change'"> | ||
| Configuration field: <code>{{ fix.fieldName }}</code> | ||
| </div> | ||
|
|
||
| <div class="ai-fix-diff"> | ||
| <div | ||
| class="ai-fix-removed" | ||
| *ngFor="let line of splitLines(fix.original)"> | ||
| - {{ line }} | ||
| </div> | ||
| <div | ||
| class="ai-fix-added" | ||
| *ngFor="let line of splitLines(fix.suggested)"> | ||
| + {{ line }} | ||
| </div> | ||
| </div> | ||
|
|
||
| <div class="ai-fix-actions"> | ||
| <button | ||
| nz-button | ||
| nzType="primary" | ||
| class="ai-fix-apply" | ||
| (click)="onApply()"> | ||
| <span | ||
| nz-icon | ||
| nzType="check"></span> | ||
| Apply and re-run | ||
| </button> | ||
| <button | ||
| nz-button | ||
| nzType="default" | ||
| class="ai-fix-discard" | ||
| (click)="onDiscard()"> | ||
| <span | ||
| nz-icon | ||
| nzType="close"></span> | ||
| Discard | ||
| </button> | ||
| </div> | ||
| </ng-container> | ||
| </ng-container> | ||
77 changes: 77 additions & 0 deletions
77
frontend/src/app/workspace/component/result-panel/ai-fix/ai-fix-frame.component.scss
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| /** | ||
| * Licensed to the Apache Software Foundation (ASF) under one | ||
| * or more contributor license agreements. See the NOTICE file | ||
| * distributed with this work for additional information | ||
| * regarding copyright ownership. The ASF licenses this file | ||
| * to you under the Apache License, Version 2.0 (the | ||
| * "License"); you may not use this file except in compliance | ||
| * with the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, | ||
| * software distributed under the License is distributed on an | ||
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| * KIND, either express or implied. See the License for the | ||
| * specific language governing permissions and limitations | ||
| * under the License. | ||
| */ | ||
|
|
||
| :host { | ||
| display: block; | ||
| width: 100%; | ||
| padding: 8px; | ||
| } | ||
|
|
||
| .ai-fix-status { | ||
| align-items: center; | ||
| display: flex; | ||
| gap: 8px; | ||
| padding: 8px 0; | ||
| } | ||
|
|
||
| .ai-fix-section-title { | ||
| font-weight: bold; | ||
| margin-top: 8px; | ||
| } | ||
|
|
||
| .ai-fix-explanation { | ||
| margin: 4px 0 8px; | ||
| user-select: text; | ||
| } | ||
|
|
||
| .ai-fix-field { | ||
| margin-bottom: 4px; | ||
| user-select: text; | ||
| } | ||
|
|
||
| /* Same monospace treatment the other result-panel frames use for code. */ | ||
| .ai-fix-diff { | ||
| border: 1px solid #e8e8e8; | ||
| border-radius: 2px; | ||
| font-family: monaco, serif; | ||
|
kunwp1 marked this conversation as resolved.
Outdated
|
||
| font-size: 11px; | ||
| line-height: 16px; | ||
| margin: 4px 0 8px; | ||
| overflow-x: auto; | ||
| white-space: pre; | ||
| user-select: text; | ||
| } | ||
|
|
||
| .ai-fix-removed { | ||
| background-color: #ffeef0; | ||
| color: #82071e; | ||
| padding: 0 6px; | ||
| } | ||
|
|
||
| .ai-fix-added { | ||
| background-color: #e6ffed; | ||
| color: #116329; | ||
| padding: 0 6px; | ||
| } | ||
|
|
||
| .ai-fix-actions { | ||
| display: flex; | ||
| gap: 8px; | ||
| margin-top: 8px; | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.