Repository navigation
feat(ai): implement AI autocomplete - #8300
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
WalkthroughAdds AI inline ghost-text autocomplete to Bruno's CodeMirror script editors. Extends preferences schema and Redux state with an ChangesAI Ghost-Text Autocomplete
Sequence Diagram(s)sequenceDiagram
participant User
participant CodeEditor
participant aiGhostText as aiGhostText Engine
participant ipcRenderer
participant ElectronMain as Electron Main
participant autocompletePrompts as autocomplete-prompts
participant AIProvider as AI Provider
User->>CodeEditor: types in script editor
CodeEditor->>aiGhostText: onChange event
aiGhostText->>aiGhostText: check local cache (instant reuse)
aiGhostText->>ipcRenderer: aiAutocomplete(prefix, suffix, context, requestId)
ipcRenderer->>ElectronMain: renderer:ai-autocomplete
ElectronMain->>autocompletePrompts: buildSystemPrompt(scriptType)
ElectronMain->>autocompletePrompts: formatRequestContext + formatVariableNames + formatSiblingScripts
ElectronMain->>autocompletePrompts: buildUserPrompt(prefix, suffix, formatted)
ElectronMain->>AIProvider: chat completion + STOP_SEQUENCES
AIProvider-->>ElectronMain: raw text
ElectronMain->>autocompletePrompts: cleanSuggestion(raw)
ElectronMain-->>ipcRenderer: cleaned suggestion
ipcRenderer-->>aiGhostText: suggestion text
aiGhostText->>CodeEditor: render ghost-text widget at cursor
User->>CodeEditor: Tab key
CodeEditor->>aiGhostText: keydown Tab
aiGhostText->>CodeEditor: insert suggestion, mark origin
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/bruno-app/src/components/Preferences/AI/AutocompletePane.js`:
- Around line 76-80: Add stable data-testid attributes to all interactive
elements in the AutocompletePane component to enable Playwright selectors.
Specifically, add a data-testid prop to the ToggleSwitch component shown in the
diff, and also add data-testid to the other interactive elements in the ranges
mentioned (101-107, 124-139). Use descriptive test IDs that clearly identify
each control's purpose, such as using naming patterns like
"autocomplete-enabled-toggle" or similar conventions that match the component's
functionality.
In `@packages/bruno-app/src/components/Preferences/AI/index.js`:
- Around line 145-165: Add `data-testid` attributes to the two tab button
elements in the AI preferences tab control. The first button that switches to
the 'config' tab (with aria-selected={activeTab === 'config'}) should have a
unique data-testid identifier, and the second button that switches to the
'autocomplete' tab (with aria-selected={activeTab === 'autocomplete'}) should
also have a unique data-testid identifier. These identifiers will allow
Playwright tests to reliably select and interact with these tab controls without
relying on brittle selectors.
- Around line 242-245: The enabled-provider check in the hasConfiguredProvider
block is using p.id to access formik.values.providers, but
formik.values.providers is keyed by Object.keys(status.providers) which may not
match p.id. Replace the Object.values(status.providers) iteration with
Object.entries(status.providers) or Object.keys(status.providers) to ensure the
keys used to access formik.values.providers match the actual structure of the
formik object, so that configured and enabled providers are correctly detected.
In `@packages/bruno-app/src/utils/ai/index.js`:
- Around line 84-107: The collectSiblingScripts function currently breaks from
the loop as soon as it reaches maxCount matching scripts, returning the first N
scripts found. To collect the last N scripts instead, remove the early break
condition that checks if out.length >= maxCount, and after the loop completes,
return only the last maxCount items from the out array using array slicing to
ensure the function returns the most recent scripts rather than the oldest ones.
In `@packages/bruno-app/src/utils/codemirror/aiGhostText.js`:
- Around line 296-307: In the onChange handler function, add immediate
cancellation of any in-flight autocomplete requests rather than deferring
cancellation until the next fetch cycle. Specifically, cancel the request
immediately when changeObj.origin is not '+ai-autocomplete' or when edit
conditions indicate a new fetch is needed, rather than waiting until
scheduleFetch is called. Additionally, apply the same immediate cancellation
logic to the blur event handler (around lines 318-320) to prevent stale requests
from continuing after blur. This ensures that provider calls are not wasted and
reduces stale-response races.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: b3d463e5-b667-4086-81d2-068488b6e25f
📒 Files selected for processing (16)
packages/bruno-app/src/components/CodeEditor/StyledWrapper.jspackages/bruno-app/src/components/CodeEditor/index.jspackages/bruno-app/src/components/CollectionSettings/Script/index.jspackages/bruno-app/src/components/FolderSettings/Script/index.jspackages/bruno-app/src/components/Preferences/AI/AutocompletePane.jspackages/bruno-app/src/components/Preferences/AI/StyledWrapper.jspackages/bruno-app/src/components/Preferences/AI/index.jspackages/bruno-app/src/components/RequestPane/Script/index.jspackages/bruno-app/src/components/RequestPane/Tests/index.jspackages/bruno-app/src/providers/ReduxStore/slices/app.jspackages/bruno-app/src/utils/ai/index.jspackages/bruno-app/src/utils/codemirror/aiGhostText.jspackages/bruno-electron/src/index.jspackages/bruno-electron/src/ipc/ai/autocomplete-prompts.jspackages/bruno-electron/src/ipc/ai/autocomplete.jspackages/bruno-electron/src/store/preferences.js
Inline ghost-text autocomplete in script editors with three trigger modes (aggressive / debounced / manual), per-feature model picker, and rich context shipped to the model (request HTTP context, env/global/collection variable names, last few sibling scripts of the same type). - New IPC handler renderer:ai-autocomplete with backend LRU+TTL cache and abortable in-flight requests. - CodeMirror 5 ghost-text engine wired into Pre-Request, Post-Response, Tests, Folder and Collection script editors. - Preferences > AI is now a tabbed pane: Configuration + Autocomplete.
ff5748e to
a9ae605
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/bruno-app/src/components/Preferences/AI/index.js (1)
145-167: 🧹 Nitpick | 🔵 Trivial | 💤 Low valueMinor a11y enhancement: link tabs to panels with
id/aria-controls.The tab buttons lack
aria-controlsand the panels lackidattributes to properly associate them. This is optional but would improve screen reader navigation.<button type="button" role="tab" aria-selected={activeTab === 'config'} + aria-controls="ai-tabpanel-config" className={`ai-tab ${activeTab === 'config' ? 'active' : ''}`} onClick={() => setActiveTab('config')} data-testid="ai-tab-config" > ... {activeTab === 'config' && ( - <div className="ai-tab-panel" role="tabpanel"> + <div id="ai-tabpanel-config" className="ai-tab-panel" role="tabpanel" aria-labelledby="ai-tab-config">Same pattern for the autocomplete tab/panel.
Also applies to: 176-177, 236-237
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/bruno-app/src/components/Preferences/AI/index.js` around lines 145 - 167, The tab buttons in the AI preferences component lack proper accessibility associations with their content panels. Add an `aria-controls` attribute to each tab button (the ones with role="tab" for 'config' and 'autocomplete' tabs) that references the ID of its corresponding panel. Then add matching `id` attributes to the panel container divs that display the tab content. For example, the 'config' tab button should have aria-controls pointing to the ID of the configuration panel div, and the 'autocomplete' tab button should point to the autocomplete panel. Apply this same pattern to any other tabs mentioned in the related code sections referenced in the comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/bruno-app/src/components/Preferences/AI/index.js`:
- Around line 145-167: The tab buttons in the AI preferences component lack
proper accessibility associations with their content panels. Add an
`aria-controls` attribute to each tab button (the ones with role="tab" for
'config' and 'autocomplete' tabs) that references the ID of its corresponding
panel. Then add matching `id` attributes to the panel container divs that
display the tab content. For example, the 'config' tab button should have
aria-controls pointing to the ID of the configuration panel div, and the
'autocomplete' tab button should point to the autocomplete panel. Apply this
same pattern to any other tabs mentioned in the related code sections referenced
in the comment.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 432e4b42-bdab-4fe4-b035-f5f7aae9115a
📒 Files selected for processing (16)
packages/bruno-app/src/components/CodeEditor/StyledWrapper.jspackages/bruno-app/src/components/CodeEditor/index.jspackages/bruno-app/src/components/CollectionSettings/Script/index.jspackages/bruno-app/src/components/FolderSettings/Script/index.jspackages/bruno-app/src/components/Preferences/AI/AutocompletePane.jspackages/bruno-app/src/components/Preferences/AI/StyledWrapper.jspackages/bruno-app/src/components/Preferences/AI/index.jspackages/bruno-app/src/components/RequestPane/Script/index.jspackages/bruno-app/src/components/RequestPane/Tests/index.jspackages/bruno-app/src/providers/ReduxStore/slices/app.jspackages/bruno-app/src/utils/ai/index.jspackages/bruno-app/src/utils/codemirror/aiGhostText.jspackages/bruno-electron/src/index.jspackages/bruno-electron/src/ipc/ai/autocomplete-prompts.jspackages/bruno-electron/src/ipc/ai/autocomplete.jspackages/bruno-electron/src/store/preferences.js
✅ Files skipped from review due to trivial changes (3)
- packages/bruno-app/src/providers/ReduxStore/slices/app.js
- packages/bruno-app/src/components/Preferences/AI/StyledWrapper.js
- packages/bruno-app/src/components/CodeEditor/StyledWrapper.js
🚧 Files skipped from review as they are similar to previous changes (10)
- packages/bruno-electron/src/index.js
- packages/bruno-app/src/components/CollectionSettings/Script/index.js
- packages/bruno-app/src/components/FolderSettings/Script/index.js
- packages/bruno-app/src/components/RequestPane/Tests/index.js
- packages/bruno-app/src/components/CodeEditor/index.js
- packages/bruno-electron/src/store/preferences.js
- packages/bruno-app/src/utils/ai/index.js
- packages/bruno-app/src/components/Preferences/AI/AutocompletePane.js
- packages/bruno-electron/src/ipc/ai/autocomplete-prompts.js
- packages/bruno-app/src/components/RequestPane/Script/index.js
utkarsh-bruno
left a comment
There was a problem hiding this comment.
Quick question :
We use Esc to cancel the ghost suggestion. If i type "bru.", the hints dropdown would open up and if i have a trigger on ai auto suggestion, then the ghost suggestion would too.
Esc also cancels the method dropdown, I guess, so I am guessing it will now only cancel the ai suggestion and not remove the hints dropdown.
If that's intended behaviour, i think it should be fine.
Rest of it looks good to me.
Description
JIRA
Contribution Checklist:
Note: Keeping the PR small and focused helps make it easier to review and merge. If you have multiple changes you want to make, please consider submitting them as separate pull requests.
Publishing to New Package Managers
Please see here for more information.
Summary by CodeRabbit
Release Notes