-
Notifications
You must be signed in to change notification settings - Fork 15
feat(model): implement dynamic model selection with custom model support #1
base: master
Are you sure you want to change the base?
Conversation
- Add 'claudex.customModel' configuration for user-defined model list - Implement config watcher in ClaudeClient to push model updates to webview - Support model parameter in chat/send request payload - Add reactive modelState in messageBus for global model selection - Render model dropdown dynamically from system/ready payload - Add "Manage Models" entry to open settings page directly This feature allows users to configure custom models via settings and switch between them seamlessly in the chat interface. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Reviewer's GuideThis PR adds dynamic model selection by introducing a custom model configuration and watcher in the extension that pushes updated model lists and the selected model to the webview, extends the chat/send flow to include the model parameter, and implements a reactive global modelState in the webview to render a dynamic dropdown and open settings directly. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
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.
Hey there - I've reviewed your changes and they look great!
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location> `src/services/claude/client.ts:70-75` </location>
<code_context>
+ e.affectsConfiguration('claudex.model')
+ ) {
+ const cfg2 = vscode.workspace.getConfiguration('claudex');
+ const custom2 = (cfg2.get<string>('customModel') || '')
+ .split(',')
+ .map(s => s.trim())
+ .filter(Boolean);
+ const models2 = Array.from(new Set([...builtInModels, ...custom2]));
+ const selected2 = cfg2.get<string>('model') || models2[0] || 'claude-4-sonnet';
</code_context>
<issue_to_address>
**suggestion:** Consider normalizing model names to avoid duplicates due to whitespace or casing.
Trimming and filtering helps, but without normalizing case or whitespace, users may still create duplicate model entries. Consider converting names to lower case or documenting the expected format.
```suggestion
const custom2 = (cfg2.get<string>('customModel') || '')
.split(',')
.map(s => s.trim().toLowerCase())
.filter(Boolean);
const models2 = Array.from(new Set([...builtInModels.map(m => m.toLowerCase()), ...custom2]));
const selected2 = (cfg2.get<string>('model') || models2[0] || 'claude-4-sonnet').toLowerCase();
```
</issue_to_address>
### Comment 2
<location> `webview/src/services/messageBus.ts:228-229` </location>
<code_context>
+ // 更新模型列表
+ if (Array.isArray(message.payload.models)) {
+ const newOptions = message.payload.models.slice();
+ modelState.options = newOptions;
+
+ // 如果当前选择不在新列表里,则回退到推荐或第一个
</code_context>
<issue_to_address>
**suggestion:** Direct assignment to reactive array may not trigger reactivity in some cases.
If UI updates are inconsistent, try replacing the array contents with splice: modelState.options.splice(0, modelState.options.length, ...newOptions).
```suggestion
const newOptions = message.payload.models.slice();
modelState.options.splice(0, modelState.options.length, ...newOptions);
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| const custom2 = (cfg2.get<string>('customModel') || '') | ||
| .split(',') | ||
| .map(s => s.trim()) | ||
| .filter(Boolean); | ||
| const models2 = Array.from(new Set([...builtInModels, ...custom2])); | ||
| const selected2 = cfg2.get<string>('model') || models2[0] || 'claude-4-sonnet'; |
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.
suggestion: Consider normalizing model names to avoid duplicates due to whitespace or casing.
Trimming and filtering helps, but without normalizing case or whitespace, users may still create duplicate model entries. Consider converting names to lower case or documenting the expected format.
| const custom2 = (cfg2.get<string>('customModel') || '') | |
| .split(',') | |
| .map(s => s.trim()) | |
| .filter(Boolean); | |
| const models2 = Array.from(new Set([...builtInModels, ...custom2])); | |
| const selected2 = cfg2.get<string>('model') || models2[0] || 'claude-4-sonnet'; | |
| const custom2 = (cfg2.get<string>('customModel') || '') | |
| .split(',') | |
| .map(s => s.trim().toLowerCase()) | |
| .filter(Boolean); | |
| const models2 = Array.from(new Set([...builtInModels.map(m => m.toLowerCase()), ...custom2])); | |
| const selected2 = (cfg2.get<string>('model') || models2[0] || 'claude-4-sonnet').toLowerCase(); |
| const newOptions = message.payload.models.slice(); | ||
| modelState.options = newOptions; |
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.
suggestion: Direct assignment to reactive array may not trigger reactivity in some cases.
If UI updates are inconsistent, try replacing the array contents with splice: modelState.options.splice(0, modelState.options.length, ...newOptions).
| const newOptions = message.payload.models.slice(); | |
| modelState.options = newOptions; | |
| const newOptions = message.payload.models.slice(); | |
| modelState.options.splice(0, modelState.options.length, ...newOptions); |
This feature allows users to configure custom models via settings and switch between them seamlessly in the chat interface.
🤖 Generated with Claude Code
Summary by Sourcery
Implement dynamic model selection with custom model support by introducing a new configuration setting, watching for setting changes, extending the messaging protocol, and updating the UI to render and switch between models dynamically.
New Features:
Enhancements: