-
Notifications
You must be signed in to change notification settings - Fork 473
feat: Add support for creating new model configs in ModelConfigDialog #506
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
- Add 'Add New Config' option in ModelSelector for UI, IDEA, and VSCode versions - Support new config mode when currentConfigName is null - Add i18n strings for 'addNewConfig' and 'add' in English and Chinese - Create ModelConfigDialog component for VSCode webview - Update IdeaAgentViewModel to support new config mode - Add onAddNewConfig callback throughout the component hierarchy This allows users to create new model configurations instead of only being able to edit existing ones.
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughAdds an "Add New Config" flow across IntelliJ and VSCode: new UI actions, dialog component, ViewModel state to distinguish add vs edit, config-save plumbing in the extension, and localization strings. Changes
sequenceDiagram
participant User
participant UI as Client UI
participant App as Webview/App/Compose
participant VM as ViewModel
participant Dialog as ModelConfigDialog
participant Ext as Extension (chat-view)
participant CM as ConfigManager
User->>UI: Click "Add New Config"
UI->>App: onAddNewConfig()
App->>VM: showAddNewConfigDialog() / set isNewConfig=true
VM->>Dialog: open dialog (currentConfig = fresh, currentName=null)
User->>Dialog: Fill form → Save
Dialog->>Ext: postMessage(saveModelConfig, data with isNewConfig)
Ext->>CM: saveConfig(data, setActive?)
CM-->>Ext: persisted, possibly renamed unique name
Ext->>App: post configs update & success
App->>UI: refresh list / close dialog
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25–35 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
|
augment review |
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.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaAgentApp.kt (1)
320-329: Potential bug in unique name generation for new configs.The name conflict check uses
currentConfigNamefrom the outer scope (line 324), but when creating a new config (isNewConfig = true),currentConfigNamestill holds the previously active config's name (notnull). This means if a user creates a new config with the same name as the currently active config, the conditioncurrentConfigName != configNamewould befalse, and auto-rename would NOT trigger - potentially overwriting the existing config.Consider using
dialogConfigNameinstead:val finalConfigName = - if (currentConfigName != configName && configName in existingNames) { + if (dialogConfigName != configName && configName in existingNames) { // Auto-increment: my-glm -> my-glm-1 -> my-glm-2, etc. ConfigManager.generateUniqueConfigName(configName, existingNames) } else { configName }
🧹 Nitpick comments (4)
mpp-vscode/webview/src/App.tsx (1)
513-513: Consider resetting all dialog state on close.The
onClosehandler only resetsshowModelConfigDialog. For consistency with the Kotlin implementation (which resets bothshowConfigDialogandisNewConfigon dismiss), consider also resettingmodelConfigDialogConfigandisNewConfig:- onClose={() => setShowModelConfigDialog(false)} + onClose={() => { + setShowModelConfigDialog(false); + setModelConfigDialogConfig(null); + setIsNewConfig(false); + }}mpp-vscode/webview/src/components/ModelConfigDialog.tsx (3)
57-76: Potential state persistence issue when reopening dialog.The useEffect has two branches but doesn't handle the case when
isOpen=true,currentConfig=null, andisNewConfig=false. In this scenario, old form values from a previous interaction would persist. While the typical usage may avoid this, consider adding an else branch or always resetting state when opening:useEffect(() => { if (isOpen && currentConfig) { setConfigName(currentConfig.name || ''); setProvider(currentConfig.provider || 'openai'); setModel(currentConfig.model || ''); setApiKey(currentConfig.apiKey || ''); setBaseUrl(currentConfig.baseUrl || ''); setTemperature(currentConfig.temperature?.toString() || '0.7'); setMaxTokens(currentConfig.maxTokens?.toString() || '8192'); } else if (isOpen && isNewConfig) { // Reset to defaults for new config setConfigName(''); setProvider('openai'); setModel(''); setApiKey(''); setBaseUrl(''); setTemperature('0.7'); setMaxTokens('8192'); + } else if (isOpen) { + // Fallback: reset if dialog opened without clear intent + setConfigName(''); + setProvider('openai'); + setModel(''); + setApiKey(''); + setBaseUrl(''); + setTemperature('0.7'); + setMaxTokens('8192'); } }, [isOpen, currentConfig, isNewConfig]);
83-116: Consider improving validation UX and save confirmation.The current implementation has a few user experience concerns:
alert() for validation: While functional, alerts are disruptive and not modern UX. Consider using inline error messages below each field.
No save confirmation: The dialog closes immediately after
postMessagewithout waiting for confirmation from the extension. If the save operation fails on the extension side, the user won't see any feedback.Missing numeric validation: Temperature is constrained in HTML (min="0" max="2") but
parseFloatdoesn't enforce this. Consider validating the parsed values:const tempValue = parseFloat(temperature); if (isNaN(tempValue) || tempValue < 0 || tempValue > 2) { alert('Temperature must be between 0 and 2'); return; }
27-38: Consider extracting constants and types for better maintainability.The
PROVIDERSconstant and the message types used inpostMessagecould be extracted to shared files:
- Move
PROVIDERSto a constants file (e.g.,constants/providers.ts) for reuse across components.- Define TypeScript types for the
saveModelConfigmessage payload in a types file.This would improve type safety and make it easier to maintain consistency across the codebase.
// types/messages.ts export interface SaveModelConfigMessage { type: 'saveModelConfig'; data: { name: string; provider: string; model: string; apiKey: string; baseUrl?: string; temperature: number; maxTokens: number; isNewConfig: boolean; }; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/editor/IdeaModelSelector.kt(2 hunks)mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/editor/SwingBottomToolbar.kt(3 hunks)mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaAgentApp.kt(5 hunks)mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaAgentViewModel.kt(2 hunks)mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaDevInInputArea.kt(4 hunks)mpp-ui/src/commonMain/i18n/cc/unitmesh/devins/ui/i18n/AutoDevStrings_en.properties(2 hunks)mpp-ui/src/commonMain/i18n/cc/unitmesh/devins/ui/i18n/AutoDevStrings_zh.properties(2 hunks)mpp-ui/src/commonMain/kotlin/cc/unitmesh/devins/ui/compose/editor/ModelSelector.kt(3 hunks)mpp-ui/src/commonMain/kotlin/cc/unitmesh/devins/ui/i18n/I18n.kt(2 hunks)mpp-vscode/webview/src/App.tsx(5 hunks)mpp-vscode/webview/src/components/ChatInput.tsx(3 hunks)mpp-vscode/webview/src/components/ModelConfigDialog.css(1 hunks)mpp-vscode/webview/src/components/ModelConfigDialog.tsx(1 hunks)mpp-vscode/webview/src/components/ModelSelector.tsx(2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{kt,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never use hardcoded colors - always use design tokens from the design system
Files:
mpp-vscode/webview/src/components/ChatInput.tsxmpp-ui/src/commonMain/kotlin/cc/unitmesh/devins/ui/i18n/I18n.ktmpp-vscode/webview/src/components/ModelSelector.tsxmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/editor/SwingBottomToolbar.ktmpp-vscode/webview/src/components/ModelConfigDialog.tsxmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/editor/IdeaModelSelector.ktmpp-ui/src/commonMain/kotlin/cc/unitmesh/devins/ui/compose/editor/ModelSelector.ktmpp-vscode/webview/src/App.tsxmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaDevInInputArea.ktmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaAgentViewModel.ktmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaAgentApp.kt
**/*.kt
📄 CodeRabbit inference engine (AGENTS.md)
**/*.kt: Useexpect/actualpattern for platform-specific code (for example:Platformimplementations)
Use concrete classes (not interfaces) andPromise(notFlow) for @JsExport annotations
Avoid emoji and UTF-8 characters in WASM code
When modifyingCodingAgentRenderer, update ALL implementations:DefaultCodingAgentRenderer,ComposeRenderer,JewelRenderer,ServerSideRenderer, andJsRendererAdapterin Kotlin
When modifyingCodingAgentRenderer, update JVM CLI implementations:CodingCliRendererandConsoleRenderer
UseAutoDevColorsorMaterialTheme.colorSchemefor Compose styling
Files:
mpp-ui/src/commonMain/kotlin/cc/unitmesh/devins/ui/i18n/I18n.ktmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/editor/SwingBottomToolbar.ktmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/editor/IdeaModelSelector.ktmpp-ui/src/commonMain/kotlin/cc/unitmesh/devins/ui/compose/editor/ModelSelector.ktmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaDevInInputArea.ktmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaAgentViewModel.ktmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaAgentApp.kt
🧠 Learnings (2)
📚 Learning: 2025-12-07T08:40:10.850Z
Learnt from: CR
Repo: phodal/auto-dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-07T08:40:10.850Z
Learning: Applies to mpp-vscode/src/**/*.ts : When modifying `CodingAgentRenderer`, update VSCode implementations: `mpp-vscode/src/bridge/mpp-core.ts` and `mpp-vscode/src/providers/chat-view.ts`
Applied to files:
mpp-vscode/webview/src/components/ModelConfigDialog.cssmpp-vscode/webview/src/components/ChatInput.tsxmpp-vscode/webview/src/components/ModelSelector.tsxmpp-vscode/webview/src/components/ModelConfigDialog.tsxmpp-vscode/webview/src/App.tsx
📚 Learning: 2025-12-07T08:40:10.850Z
Learnt from: CR
Repo: phodal/auto-dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-07T08:40:10.850Z
Learning: Run `./gradlew :mpp-ui:generateI18n4kFiles` command when updating i18n resources
Applied to files:
mpp-ui/src/commonMain/kotlin/cc/unitmesh/devins/ui/i18n/I18n.kt
🧬 Code graph analysis (5)
mpp-vscode/webview/src/components/ModelSelector.tsx (1)
mpp-ui/src/commonMain/kotlin/cc/unitmesh/devins/ui/compose/editor/ModelSelector.kt (1)
ModelSelector(26-224)
mpp-vscode/webview/src/components/ModelConfigDialog.tsx (2)
mpp-vscode/webview/src/hooks/useVSCode.ts (1)
useVSCode(100-119)mpp-vscode/src/providers/chat-view.ts (1)
postMessage(267-269)
mpp-ui/src/commonMain/kotlin/cc/unitmesh/devins/ui/compose/editor/ModelSelector.kt (1)
mpp-vscode/webview/src/components/ModelSelector.tsx (1)
ModelConfig(11-15)
mpp-vscode/webview/src/App.tsx (2)
mpp-vscode/webview/src/components/ModelSelector.tsx (1)
ModelConfig(11-15)mpp-vscode/src/bridge/mpp-core.ts (1)
ModelConfig(38-45)
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaAgentApp.kt (2)
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/compose/IdeaComposeEffects.kt (3)
IdeaLaunchedEffect(73-85)IdeaLaunchedEffect(90-103)IdeaLaunchedEffect(108-122)mpp-vscode/webview/src/components/ModelSelector.tsx (1)
ModelConfig(11-15)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Agent
- GitHub Check: Build
- GitHub Check: Test mpp-core (KMP)
🔇 Additional comments (22)
mpp-ui/src/commonMain/i18n/cc/unitmesh/devins/ui/i18n/AutoDevStrings_en.properties (1)
10-10: LGTM! Remember to regenerate i18n files.The new i18n keys are correctly formatted and follow the existing naming conventions.
Based on learnings, please run the following command after adding these i18n keys:
./gradlew :mpp-ui:generateI18n4kFilesAlso applies to: 29-29
mpp-ui/src/commonMain/i18n/cc/unitmesh/devins/ui/i18n/AutoDevStrings_zh.properties (1)
10-10: LGTM!The Chinese translations are correctly added and align with the corresponding English keys.
Also applies to: 29-29
mpp-ui/src/commonMain/kotlin/cc/unitmesh/devins/ui/i18n/I18n.kt (1)
69-69: LGTM!The new string properties correctly map to the i18n keys and follow the existing pattern in the codebase.
Also applies to: 89-89
mpp-vscode/webview/src/components/ChatInput.tsx (1)
16-16: LGTM!The
onAddNewConfigcallback is properly added to the component interface, correctly destructured, and appropriately forwarded to theModelSelectorcomponent. The optional nature maintains backward compatibility.Also applies to: 38-38, 230-230
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/editor/SwingBottomToolbar.kt (1)
35-35: LGTM!The "Add New Config" button is properly integrated with appropriate icon, tooltip, and callback wiring. The implementation follows the existing pattern for other toolbar actions.
Also applies to: 56-64, 153-155
mpp-vscode/webview/src/components/ModelConfigDialog.css (1)
1-167: LGTM!The CSS properly uses VSCode theme variables throughout (no hardcoded colors), implements standard modal dialog patterns, and provides appropriate visual feedback for interactive elements. The styling is consistent with VSCode design conventions.
mpp-vscode/webview/src/components/ModelSelector.tsx (1)
22-22: LGTM!The
onAddNewConfigprop is correctly added to the interface and properly destructured in the component.Also applies to: 29-30
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/editor/IdeaModelSelector.kt (1)
38-38: LGTM!The
onAddNewConfigcallback parameter is correctly added to the function signature, maintaining consistency with other callback parameters.mpp-ui/src/commonMain/kotlin/cc/unitmesh/devins/ui/compose/editor/ModelSelector.kt (4)
30-30: LGTM!The
isNewConfigstate is appropriately scoped within the composable and correctly defaults tofalse.
139-154: LGTM!The "Add New Config" menu item follows the established pattern, uses proper i18n strings, and correctly sets the state before opening the dialog.
156-171: LGTM!Explicitly resetting
isNewConfig = falsewhen editing ensures the dialog correctly distinguishes between creating and editing configurations.
174-222: LGTM!The dialog invocation logic correctly handles both new and edit modes:
- Fresh
ModelConfig()andnullname for new configs- Existing config and name for edits
- Proper state cleanup on dismiss
- Auto-rename logic correctly handles name conflicts for both scenarios
mpp-vscode/webview/src/App.tsx (3)
78-81: LGTM!The new state variables for the model config dialog are appropriately initialized:
showModelConfigDialogcontrols visibilitymodelConfigDialogConfigholds the config being edited (or null for new)isNewConfigdistinguishes between add and edit modes
335-351: LGTM!Both handlers are correctly implemented:
handleOpenConfigprefers in-dialog editing when a config exists, with fallback to extensionhandleAddNewConfigcorrectly initializes state for creating a new configuration- Dependencies in
useCallbackare properly specified
509-517: > Likely an incorrect or invalid review comment.mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaAgentViewModel.kt (2)
84-85: LGTM!The
isNewConfigstate follows the established pattern in this ViewModel:
- Private
MutableStateFlowfor internal mutation- Public
StateFlowviaasStateFlow()for external observation
592-606: LGTM!The new dialog control methods cleanly encapsulate the state transitions:
showAddNewConfigDialog()sets new-config mode and shows the dialogshowEditConfigDialog()sets edit mode and shows the dialogThis provides a clear API for UI components to trigger the appropriate dialog mode.
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaAgentApp.kt (2)
68-68: LGTM!The
isNewConfigstate and its collection viaIdeaLaunchedEffectfollow the established pattern used for other ViewModel states in this file.Also applies to: 93-95
224-225: LGTM!The callback wiring correctly connects UI actions to ViewModel methods:
onConfigureClick→showEditConfigDialog()for editingonAddNewConfig→showAddNewConfigDialog()for creatingmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaDevInInputArea.kt (3)
83-83: LGTM!The new
onAddNewConfigparameter follows the established pattern of other callbacks in this composable (e.g.,onConfigSelect,onConfigureClick), with an appropriate default empty lambda.
120-123: LGTM!The
DisposableEffectfor propagatingonAddNewConfigfollows the same pattern used foronConfigSelectandonConfigureClick.
337-339: LGTM!The
setOnAddNewConfigmethod correctly delegates toSwingBottomToolbar.setOnAddNewConfig, which is properly implemented and wired to the add config button in the toolbar's initialization.
| // Add New Config button | ||
| selectableItem( | ||
| selected = false, | ||
| onClick = { | ||
| onAddNewConfig() | ||
| expanded = false | ||
| } | ||
| ) { | ||
| Row( | ||
| horizontalArrangement = Arrangement.spacedBy(8.dp), | ||
| verticalAlignment = Alignment.CenterVertically | ||
| ) { | ||
| Icon( | ||
| imageVector = IdeaComposeIcons.Add, | ||
| contentDescription = null, | ||
| tint = JewelTheme.globalColors.text.normal, | ||
| modifier = Modifier.size(16.dp) | ||
| ) | ||
| Text( | ||
| text = "Add New Config", | ||
| style = JewelTheme.defaultTextStyle.copy(fontSize = 13.sp) | ||
| ) | ||
| } | ||
| } |
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.
🛠️ Refactor suggestion | 🟠 Major
Use i18n for the "Add New Config" label.
Line 154 contains a hardcoded string. For consistency with the i18n infrastructure added in this PR (see Strings.addNewConfig in I18n.kt), the label should use the localization key.
Apply this diff to use the i18n string:
Text(
- text = "Add New Config",
+ text = Strings.addNewConfig,
style = JewelTheme.defaultTextStyle.copy(fontSize = 13.sp)
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Add New Config button | |
| selectableItem( | |
| selected = false, | |
| onClick = { | |
| onAddNewConfig() | |
| expanded = false | |
| } | |
| ) { | |
| Row( | |
| horizontalArrangement = Arrangement.spacedBy(8.dp), | |
| verticalAlignment = Alignment.CenterVertically | |
| ) { | |
| Icon( | |
| imageVector = IdeaComposeIcons.Add, | |
| contentDescription = null, | |
| tint = JewelTheme.globalColors.text.normal, | |
| modifier = Modifier.size(16.dp) | |
| ) | |
| Text( | |
| text = "Add New Config", | |
| style = JewelTheme.defaultTextStyle.copy(fontSize = 13.sp) | |
| ) | |
| } | |
| } | |
| // Add New Config button | |
| selectableItem( | |
| selected = false, | |
| onClick = { | |
| onAddNewConfig() | |
| expanded = false | |
| } | |
| ) { | |
| Row( | |
| horizontalArrangement = Arrangement.spacedBy(8.dp), | |
| verticalAlignment = Alignment.CenterVertically | |
| ) { | |
| Icon( | |
| imageVector = IdeaComposeIcons.Add, | |
| contentDescription = null, | |
| tint = JewelTheme.globalColors.text.normal, | |
| modifier = Modifier.size(16.dp) | |
| ) | |
| Text( | |
| text = Strings.addNewConfig, | |
| style = JewelTheme.defaultTextStyle.copy(fontSize = 13.sp) | |
| ) | |
| } | |
| } |
🤖 Prompt for AI Agents
In mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/editor/IdeaModelSelector.kt
around lines 135-158 there is a hardcoded label "Add New Config"; replace that
literal with the i18n key by using Strings.addNewConfig (importing the Strings
object from I18n.kt if needed) so the Text composable uses the localized string
instead of the hardcoded English text; ensure the correct accessor is used
consistent with the project's i18n pattern (e.g. Strings.addNewConfig or the
project's stringResource wrapper) and keep the rest of the Text styling
unchanged.
| return ( | ||
| <div className="model-config-dialog-overlay" onClick={onClose}> | ||
| <div className="model-config-dialog" onClick={(e) => e.stopPropagation()}> | ||
| <div className="model-config-dialog-header"> | ||
| <h2>{isNewConfig ? 'Add New Model Config' : 'Configure Model'}</h2> | ||
| <button className="close-button" onClick={onClose}>×</button> | ||
| </div> | ||
|
|
||
| <div className="model-config-dialog-content"> | ||
| <div className="form-field"> | ||
| <label>Configuration Name</label> | ||
| <input | ||
| type="text" | ||
| value={configName} | ||
| onChange={(e) => setConfigName(e.target.value)} | ||
| placeholder="e.g., my-glm, work-gpt4" | ||
| /> | ||
| </div> | ||
|
|
||
| <div className="form-field"> | ||
| <label>Provider</label> | ||
| <select value={provider} onChange={(e) => setProvider(e.target.value)}> | ||
| {PROVIDERS.map(p => ( | ||
| <option key={p.value} value={p.value}>{p.label}</option> | ||
| ))} | ||
| </select> | ||
| </div> | ||
|
|
||
| <div className="form-field"> | ||
| <label>Model</label> | ||
| <input | ||
| type="text" | ||
| value={model} | ||
| onChange={(e) => setModel(e.target.value)} | ||
| placeholder="Enter model name" | ||
| /> | ||
| </div> | ||
|
|
||
| {needsApiKey && ( | ||
| <div className="form-field"> | ||
| <label>API Key</label> | ||
| <div className="input-with-icon"> | ||
| <input | ||
| type={showApiKey ? 'text' : 'password'} | ||
| value={apiKey} | ||
| onChange={(e) => setApiKey(e.target.value)} | ||
| placeholder="Enter API key" | ||
| /> | ||
| <button | ||
| type="button" | ||
| className="toggle-visibility" | ||
| onClick={() => setShowApiKey(!showApiKey)} | ||
| > | ||
| {showApiKey ? '👁️' : '👁️🗨️'} | ||
| </button> | ||
| </div> | ||
| </div> | ||
| )} | ||
|
|
||
| {needsBaseUrl && ( | ||
| <div className="form-field"> | ||
| <label>Base URL</label> | ||
| <input | ||
| type="text" | ||
| value={baseUrl} | ||
| onChange={(e) => setBaseUrl(e.target.value)} | ||
| placeholder={ | ||
| provider === 'ollama' ? 'http://localhost:11434' : | ||
| provider === 'glm' ? 'https://open.bigmodel.cn/api/paas/v4' : | ||
| provider === 'qwen' ? 'https://dashscope.aliyuncs.com/api/v1' : | ||
| provider === 'kimi' ? 'https://api.moonshot.cn/v1' : | ||
| 'https://api.example.com/v1' | ||
| } | ||
| /> | ||
| </div> | ||
| )} | ||
|
|
||
| <div className="form-field"> | ||
| <button | ||
| className="toggle-advanced" | ||
| onClick={() => setShowAdvanced(!showAdvanced)} | ||
| > | ||
| {showAdvanced ? '▼' : '▶'} Advanced Parameters | ||
| </button> | ||
| </div> | ||
|
|
||
| {showAdvanced && ( | ||
| <> | ||
| <div className="form-field"> | ||
| <label>Temperature</label> | ||
| <input | ||
| type="number" | ||
| step="0.1" | ||
| min="0" | ||
| max="2" | ||
| value={temperature} | ||
| onChange={(e) => setTemperature(e.target.value)} | ||
| placeholder="0.7" | ||
| /> | ||
| </div> | ||
|
|
||
| <div className="form-field"> | ||
| <label>Max Tokens</label> | ||
| <input | ||
| type="number" | ||
| value={maxTokens} | ||
| onChange={(e) => setMaxTokens(e.target.value)} | ||
| placeholder="8192" | ||
| /> | ||
| </div> | ||
| </> | ||
| )} | ||
| </div> | ||
|
|
||
| <div className="model-config-dialog-footer"> | ||
| <button className="cancel-button" onClick={onClose}>Cancel</button> | ||
| <button className="save-button" onClick={handleSave}>Save</button> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| ); |
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.
Add essential accessibility features to the dialog.
The dialog is missing several accessibility features that prevent keyboard-only users and screen reader users from effectively using the form:
-
Labels not linked to inputs: Add
htmlForattributes to labels and correspondingidattributes to inputs. -
Missing ARIA labels: Add
aria-labelto icon buttons, especially the close button (×) and visibility toggle. -
No keyboard support: Add ESC key handler to close the dialog.
-
No focus management: Implement focus trap within dialog and restore focus when closing.
-
Missing dialog semantics: Add proper ARIA attributes to the dialog container:
- <div className="model-config-dialog" onClick={(e) => e.stopPropagation()}>
+ <div
+ className="model-config-dialog"
+ role="dialog"
+ aria-labelledby="dialog-title"
+ aria-modal="true"
+ onClick={(e) => e.stopPropagation()}
+ >
<div className="model-config-dialog-header">
- <h2>{isNewConfig ? 'Add New Model Config' : 'Configure Model'}</h2>
+ <h2 id="dialog-title">{isNewConfig ? 'Add New Model Config' : 'Configure Model'}</h2>
- <button className="close-button" onClick={onClose}>×</button>
+ <button className="close-button" onClick={onClose} aria-label="Close dialog">×</button>
</div>Example for linking labels to inputs:
<div className="form-field">
- <label>Configuration Name</label>
+ <label htmlFor="config-name">Configuration Name</label>
<input
+ id="config-name"
type="text"
value={configName}
onChange={(e) => setConfigName(e.target.value)}
placeholder="e.g., my-glm, work-gpt4"
/>
</div>Add ESC key handler:
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
onClose();
}
};
if (isOpen) {
document.addEventListener('keydown', handleKeyDown);
return () => document.removeEventListener('keydown', handleKeyDown);
}
}, [isOpen, onClose]);🤖 Prompt for AI Agents
mpp-vscode/webview/src/components/ModelConfigDialog.tsx around lines 118-238:
the dialog lacks accessibility wiring—labels are not linked to inputs, icon
buttons have no aria labels, there is no ESC key close handler, no focus
management or focus trap, and the dialog lacks proper dialog semantics; fix by
adding id attributes to each input and matching htmlFor on labels, add
aria-label (and title) to the close and API-key visibility toggle buttons, add
role="dialog", aria-modal="true" and aria-labelledby pointing at the dialog
header, implement an effect that saves document.activeElement on open and
restores focus on close, autofocus the first form control (use a ref), add a
keydown listener to close on Escape, and implement a simple JS focus trap inside
the dialog (handle Tab and Shift+Tab to cycle focusable elements) so
keyboard-only users cannot tab out of the modal until it is closed.
| {onAddNewConfig && ( | ||
| <> | ||
| <button | ||
| className="dropdown-item configure-item" | ||
| onClick={() => { | ||
| onAddNewConfig(); | ||
| setIsOpen(false); | ||
| }} | ||
| > | ||
| <svg className="settings-icon" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"> | ||
| <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/> | ||
| </svg> | ||
| <span>Add New Config</span> | ||
| </button> | ||
| <div className="dropdown-separator" /> | ||
| </> | ||
| )} |
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.
🛠️ Refactor suggestion | 🟠 Major
Use i18n for the "Add New Config" label.
Line 110 contains a hardcoded string. For consistency with the i18n infrastructure added in this PR, the label should use the modelConfig.addNewConfig localization key.
While the UI flow is correct, proper internationalization requires using the i18n system. You'll need to import or access the i18n strings (similar to how mpp-ui uses Strings.addNewConfig) and replace the hardcoded text.
🤖 Prompt for AI Agents
In mpp-vscode/webview/src/components/ModelSelector.tsx around lines 98 to 114,
the "Add New Config" label is hardcoded; import and use the i18n string instead
(e.g., add an import for the project Strings module or the existing i18n
accessor used elsewhere in this file) and replace the literal span text with the
localized key modelConfig.addNewConfig (ensure the import path matches the
project convention, and run a quick compile to fix any import name or path
issues).
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.
Review completed. No suggestions at this time.
Comment augment review to trigger a new review at any time.
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.
Pull request overview
This PR adds the ability to create new model configurations across all three platforms (Desktop UI, IntelliJ IDEA plugin, and VSCode extension), addressing a significant usability gap where users could only edit existing configurations but not create new ones.
Key Changes:
- Added "Add New Config" menu option in model selectors with visual indicators (Add icon)
- Introduced
isNewConfigstate flag to distinguish between create and edit modes in dialogs - Added i18n strings for "Add New Config" and "Add" in English and Chinese for UI/IDEA versions
Critical Issues Identified:
- VSCode implementation is incomplete - the webview sends a
saveModelConfigmessage that has no handler in the extension backend, meaning configs cannot actually be saved - VSCode implementation lacks proper state cleanup when the dialog closes
- Missing duplicate name validation in VSCode compared to UI/IDEA implementations
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| mpp-vscode/webview/src/components/ModelSelector.tsx | Added "Add New Config" button with plus icon and callback propagation |
| mpp-vscode/webview/src/components/ModelConfigDialog.tsx | New dialog component for config editing/creation with form validation (incomplete backend integration) |
| mpp-vscode/webview/src/components/ModelConfigDialog.css | Complete styling for the model config dialog using VSCode theme variables |
| mpp-vscode/webview/src/components/ChatInput.tsx | Added onAddNewConfig callback support for propagating the action |
| mpp-vscode/webview/src/App.tsx | Added dialog state management and handlers (missing state cleanup on close) |
| mpp-ui/src/commonMain/kotlin/cc/unitmesh/devins/ui/i18n/I18n.kt | Added add and addNewConfig string accessors for i18n support |
| mpp-ui/src/commonMain/kotlin/cc/unitmesh/devins/ui/compose/editor/ModelSelector.kt | Added "Add New Config" menu item with proper i18n, state management, and unique name generation |
| mpp-ui/src/commonMain/i18n/cc/unitmesh/devins/ui/i18n/AutoDevStrings_zh.properties | Added Chinese translations for new strings |
| mpp-ui/src/commonMain/i18n/cc/unitmesh/devins/ui/i18n/AutoDevStrings_en.properties | Added English strings for new functionality |
| mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaDevInInputArea.kt | Added onAddNewConfig callback propagation through Swing components |
| mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaAgentViewModel.kt | Added isNewConfig state and helper methods for dialog mode management |
| mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/toolwindow/IdeaAgentApp.kt | Integrated new config mode with proper state handling and unique name generation |
| mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/editor/SwingBottomToolbar.kt | Added "Add New Config" button to Swing toolbar with icon |
| mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/editor/IdeaModelSelector.kt | Added "Add New Config" menu item (uses hardcoded English string instead of i18n) |
Comments suppressed due to low confidence (1)
mpp-vscode/webview/src/components/ModelSelector.tsx:126
- [nitpick] The VSCode implementation uses hardcoded English strings "Add New Config" and "Configure Model..." instead of using an internationalization (i18n) system. While the UI and IDEA versions properly support multiple languages through i18n, the VSCode implementation lacks this feature.
Consider implementing an i18n solution for the VSCode webview to support multiple languages consistently across all platforms.
<span>Add New Config</span>
</button>
<div className="dropdown-separator" />
</>
)}
<button
className="dropdown-item configure-item"
onClick={() => {
onConfigureClick();
setIsOpen(false);
}}
>
<svg className="settings-icon" width="14" height="14" viewBox="0 0 24 24" fill="currentColor">
<path d="M19.14 12.94c.04-.31.06-.63.06-.94 0-.31-.02-.63-.06-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.04.31-.06.63-.06.94s.02.63.06.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/>
</svg>
<span>Configure Model...</span>
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| // Add New Config button | ||
| val addConfigButton = JButton(AllIcons.General.Add).apply { | ||
| toolTipText = "Add New Config" |
Copilot
AI
Dec 9, 2025
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.
[nitpick] The tooltip text "Add New Config" doesn't match the menu item text used in other implementations. The UI version uses "Add New Config" (from Strings.addNewConfig) and IDEA also uses "Add New Config". However, looking at the UI version's i18n files, the Chinese translation is "新增配置" (line 29 of AutoDevStrings_zh.properties).
For better consistency and clarity, consider using a more descriptive tooltip like "Add New Model Configuration" or ensure it matches the actual menu item text exactly.
| toolTipText = "Add New Config" | |
| toolTipText = "Add New Model Configuration" |
| postMessage({ | ||
| type: 'saveModelConfig', | ||
| data: { | ||
| name: configName.trim(), | ||
| provider, | ||
| model: model.trim(), | ||
| apiKey: apiKey.trim(), | ||
| baseUrl: baseUrl.trim() || undefined, | ||
| temperature: parseFloat(temperature) || 0.7, | ||
| maxTokens: parseInt(maxTokens) || 8192, | ||
| isNewConfig | ||
| } | ||
| }); |
Copilot
AI
Dec 9, 2025
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.
The VSCode implementation sends a saveModelConfig message from the webview (line 102), but there's no corresponding handler for this message type in the extension backend (chat-view.ts). The message handler switch statement (lines 124-177 in chat-view.ts) only includes cases for sendMessage, clearHistory, action, openConfig, stopExecution, selectConfig, searchFiles, getRecentFiles, readFileContent, requestConfig, getActiveFile, getCompletions, and applyCompletion.
Without a handler for saveModelConfig, clicking the Save button in the ModelConfigDialog will not actually save the configuration. You need to add a case for saveModelConfig in the message handler and implement the logic to save the configuration to ~/.autodev/config.yaml using the ConfigManager.
| modifier = Modifier.size(16.dp) | ||
| ) | ||
| Text( | ||
| text = "Add New Config", |
Copilot
AI
Dec 9, 2025
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.
The IDEA implementation uses a hardcoded English string "Add New Config" instead of using the i18n string system. The UI version (mpp-ui) properly uses Strings.addNewConfig for internationalization support. For consistency with the codebase's i18n patterns and to support multiple languages, this should use an i18n string.
Since the i18n strings have already been added to the common I18n.kt file (Strings.addNewConfig), you should use that string here instead of the hardcoded "Add New Config".
| const handleSave = () => { | ||
| if (!configName.trim()) { | ||
| alert('Please enter a configuration name'); | ||
| return; | ||
| } | ||
| if (!model.trim()) { | ||
| alert('Please enter a model name'); | ||
| return; | ||
| } | ||
| if (needsApiKey && !apiKey.trim()) { | ||
| alert('Please enter an API key'); | ||
| return; | ||
| } | ||
| if (needsBaseUrl && !baseUrl.trim()) { | ||
| alert('Please enter a base URL'); | ||
| return; | ||
| } |
Copilot
AI
Dec 9, 2025
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.
The dialog uses alert() for validation errors, which is not consistent with VSCode's UI patterns. VSCode extensions should use vscode.window.showErrorMessage() or inline validation messages for a better user experience. However, since this is webview code, consider using inline error messages or toast notifications within the webview instead of browser alerts.
Additionally, the validation doesn't check for duplicate configuration names when creating a new config, unlike the UI version which implements this check (see mpp-ui ModelSelector.kt lines 186-193). This could lead to accidentally overwriting existing configurations.
mpp-vscode/webview/src/App.tsx
Outdated
| {showModelConfigDialog && ( | ||
| <ModelConfigDialog | ||
| isOpen={showModelConfigDialog} | ||
| onClose={() => setShowModelConfigDialog(false)} |
Copilot
AI
Dec 9, 2025
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.
When the dialog is closed via onClose, the isNewConfig state is not reset. This could lead to unexpected behavior if the user opens the "Configure Model" dialog after closing the "Add New Config" dialog, as the isNewConfig flag would still be true.
The UI version properly handles this by resetting isNewConfig to false in the onDismiss handler (see mpp-ui ModelSelector.kt lines 178-181). Consider adding similar state cleanup:
onClose={() => {
setShowModelConfigDialog(false);
setIsNewConfig(false);
setModelConfigDialogConfig(null);
}}| onClose={() => setShowModelConfigDialog(false)} | |
| onClose={() => { | |
| setShowModelConfigDialog(false); | |
| setIsNewConfig(false); | |
| setModelConfigDialogConfig(null); | |
| }} |
- Fix missing onAddNewConfig parameter in IdeaBottomToolbar - Add saveModelConfig message handler in VSCode chat-view.ts - Add saveConfig and generateUniqueConfigName methods to ConfigManager - Replace alert() with inline error messages in ModelConfigDialog - Fix state reset issue in App.tsx when closing dialog - Add error styling and validation feedback in ModelConfigDialog Fixes build error: No value passed for parameter 'onAddNewConfig'
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.
Actionable comments posted: 0
🧹 Nitpick comments (1)
mpp-vscode/src/services/config-manager.ts (1)
177-221: Consider using async fs operations for consistency.The method uses synchronous fs operations (
existsSync,mkdirSync,writeFileSync) which work correctly but could be replaced with async versions (access,mkdir,writeFile) for consistency with theload()method pattern and to avoid blocking the event loop.Example refactor:
static async saveConfig(config: LLMConfig, setActive: boolean = false): Promise<void> { try { // Ensure directory exists - if (!fs.existsSync(this.CONFIG_DIR)) { - fs.mkdirSync(this.CONFIG_DIR, { recursive: true }); - } + await fs.promises.mkdir(this.CONFIG_DIR, { recursive: true }).catch(() => {}); // Load existing config let wrapper = await this.load(); const configFile = wrapper.getConfigFile(); // ... existing logic ... // Write to file const yamlContent = yaml.stringify(configFile, { indent: 2, lineWidth: 0 }); - fs.writeFileSync(this.CONFIG_FILE, yamlContent, 'utf-8'); + await fs.promises.writeFile(this.CONFIG_FILE, yamlContent, 'utf-8'); } catch (error) { throw new Error(`Failed to save config: ${error}`); } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/editor/IdeaBottomToolbar.kt(2 hunks)mpp-vscode/src/providers/chat-view.ts(2 hunks)mpp-vscode/src/services/config-manager.ts(1 hunks)mpp-vscode/webview/src/App.tsx(5 hunks)mpp-vscode/webview/src/components/ModelConfigDialog.css(1 hunks)mpp-vscode/webview/src/components/ModelConfigDialog.tsx(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- mpp-vscode/webview/src/components/ModelConfigDialog.tsx
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
When modifying
CodingAgentRenderer, update ALL TypeScript implementations:BaseRenderer.ts,CliRenderer.ts,ServerRenderer.ts, andTuiRenderer.ts
Files:
mpp-vscode/src/services/config-manager.tsmpp-vscode/src/providers/chat-view.ts
mpp-vscode/src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
When modifying
CodingAgentRenderer, update VSCode implementations:mpp-vscode/src/bridge/mpp-core.tsandmpp-vscode/src/providers/chat-view.ts
Files:
mpp-vscode/src/services/config-manager.tsmpp-vscode/src/providers/chat-view.ts
**/*.{kt,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never use hardcoded colors - always use design tokens from the design system
Files:
mpp-vscode/src/services/config-manager.tsmpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/editor/IdeaBottomToolbar.ktmpp-vscode/webview/src/App.tsxmpp-vscode/src/providers/chat-view.ts
**/*.kt
📄 CodeRabbit inference engine (AGENTS.md)
**/*.kt: Useexpect/actualpattern for platform-specific code (for example:Platformimplementations)
Use concrete classes (not interfaces) andPromise(notFlow) for @JsExport annotations
Avoid emoji and UTF-8 characters in WASM code
When modifyingCodingAgentRenderer, update ALL implementations:DefaultCodingAgentRenderer,ComposeRenderer,JewelRenderer,ServerSideRenderer, andJsRendererAdapterin Kotlin
When modifyingCodingAgentRenderer, update JVM CLI implementations:CodingCliRendererandConsoleRenderer
UseAutoDevColorsorMaterialTheme.colorSchemefor Compose styling
Files:
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/editor/IdeaBottomToolbar.kt
🧠 Learnings (1)
📚 Learning: 2025-12-07T08:40:10.850Z
Learnt from: CR
Repo: phodal/auto-dev PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-07T08:40:10.850Z
Learning: Applies to mpp-vscode/src/**/*.ts : When modifying `CodingAgentRenderer`, update VSCode implementations: `mpp-vscode/src/bridge/mpp-core.ts` and `mpp-vscode/src/providers/chat-view.ts`
Applied to files:
mpp-vscode/webview/src/App.tsxmpp-vscode/src/providers/chat-view.tsmpp-vscode/webview/src/components/ModelConfigDialog.css
🧬 Code graph analysis (3)
mpp-vscode/src/services/config-manager.ts (1)
mpp-core/src/commonMain/kotlin/cc/unitmesh/config/ConfigFile.kt (1)
configFile(91-171)
mpp-vscode/webview/src/App.tsx (3)
mpp-vscode/webview/src/components/ModelSelector.tsx (1)
ModelConfig(11-15)mpp-vscode/src/bridge/mpp-core.ts (1)
ModelConfig(38-45)mpp-vscode/src/providers/chat-view.ts (1)
postMessage(312-314)
mpp-vscode/src/providers/chat-view.ts (1)
mpp-vscode/src/services/config-manager.ts (3)
LLMConfig(18-26)LLMProvider(13-13)ConfigManager(111-239)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Test mpp-core (KMP)
- GitHub Check: Build
🔇 Additional comments (9)
mpp-idea/src/main/kotlin/cc/unitmesh/devins/idea/editor/IdeaBottomToolbar.kt (1)
28-44: NewonAddNewConfigcallback wiring looks correct and backward compatibleThe new
onAddNewConfigparameter is added with a default value and passed straight through toIdeaModelSelector, so existing callers remain source-compatible and the add-config flow is cleanly exposed from this composable.Also applies to: 59-65
mpp-vscode/src/services/config-manager.ts (1)
226-238: LGTM!The unique name generation logic is clean and handles collisions correctly by appending incrementing numeric suffixes.
mpp-vscode/src/providers/chat-view.ts (2)
177-180: LGTM!The message handling for
saveModelConfigis properly integrated into the existing switch statement and follows the same pattern as other message handlers.
199-238: Verify that always setting the config as active is intended.Line 226 always passes
setActive: truetoConfigManager.saveConfig, which means both creating new configs and editing existing configs will set them as active. This might not be desired if a user edits a non-active config and expects it to remain inactive.Consider making the active flag conditional:
- // Save config - await ConfigManager.saveConfig(config, true); + // Save config (set as active only for new configs) + await ConfigManager.saveConfig(config, data.isNewConfig);Alternatively, if the current behavior is intentional (always activate when saving), this can be kept as-is, but it should be documented or confirmed.
mpp-vscode/webview/src/App.tsx (4)
78-81: LGTM!The state management for the model config dialog is well-structured with clear separation between dialog visibility, config data, and mode (new vs edit).
335-344: LGTM!The enhanced
handleOpenConfigcorrectly distinguishes between opening an existing config in the dialog versus falling back to opening the config file directly when no config is available.
346-351: LGTM!The
handleAddNewConfighandler correctly initializes the dialog state for creating a new configuration with an empty form.
509-521: LGTM!The ModelConfigDialog integration is complete and correct. The
onClosehandler properly resets all dialog state includingisNewConfig, which addresses the concern raised in the previous review.mpp-vscode/webview/src/components/ModelConfigDialog.css (1)
1-178: LGTM!The CSS implementation is excellent:
- Follows the coding guideline to use design tokens (VSCode CSS variables) exclusively—no hardcoded colors
- Includes proper accessibility features (focus states, keyboard navigation support)
- Responsive sizing handles various screen sizes gracefully
- Well-organized with clear class naming and structure
Summary
This PR adds support for creating new model configurations in all three versions (UI, IDEA, and VSCode) of the ModelConfigDialog.
Changes
UI Version (mpp-ui)
isNewConfigstate to distinguish between new and edit modescurrentConfigNameis null)addNewConfigandaddin English and ChineseIDEA Version (mpp-idea)
isNewConfigstate and related methods in IdeaAgentViewModelonAddNewConfigcallback support in IdeaDevInInputAreaVSCode Version (mpp-vscode)
onAddNewConfigcallback support in ChatInputProblem Solved
Previously, users could only edit existing model configurations. The model selector was a dropdown that only allowed selecting from existing configs, making it impossible to create new ones. Now users can:
Testing
Related Issues
Fixes the issue where users could only modify existing model configs and couldn't create new ones.
Summary by CodeRabbit
New Features
Localization
✏️ Tip: You can customize this high-level summary in your review settings.