Skip to content
This repository was archived by the owner on Nov 14, 2025. It is now read-only.

Conversation

@wenwen12345
Copy link

@wenwen12345 wenwen12345 commented Oct 3, 2025

  • 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

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:

  • Add 'claudex.customModel' setting to allow users to define custom models via a comma-separated list
  • Watch for 'claudex.customModel' and 'claudex.model' changes in ClaudeClient and push updated model lists and selected model to the webview
  • Support specifying a model parameter in chat/send requests and route it through the Claude agent
  • Render a dynamic model dropdown in the chat UI driven by a reactive modelState
  • Add a "Manage Models" entry in the UI to open the settings page directly for configuring models

Enhancements:

  • Refactor ButtonArea.vue and ChatPage.vue to use reactive modelState instead of hardcoded model items
  • Extend the messaging protocol to include models and selectedModel in system/ready messages and introduce a settings/open message
  • Properly dispose of the configuration watcher when the client shuts down
  • Update package.json to include schema definitions for the new 'claudex.customModel' configuration

- 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>
@sourcery-ai
Copy link

sourcery-ai bot commented Oct 3, 2025

Reviewer's Guide

This 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

Change Details Files
Backend: dynamic model config watcher and payload updates
  • Merge built-in and custom models from claudex.customModel
  • Initialize and dispose a configWatcher to push system/ready with updated models and selectedModel
  • Extend system/ready payload to include models and selectedModel
  • Handle 'settings/open' messages to open the VS Code settings UI
  • Accept an optional model field in chat/send and forward it in the request
src/services/claude/client.ts
Webview: reactive modelState and dynamic dropdown UI
  • Introduce modelState (options + selected) in messageBus and update it on system/ready
  • Render modelOptions via v-for in ButtonArea.vue and compute selectedModelLocal from modelState
  • Add 'Manage Models' dropdown item to trigger openSettings
  • Include modelState.selected when sending chat messages
webview/src/components/ButtonArea.vue
webview/src/services/messageBus.ts
webview/src/pages/ChatPage.vue
Protocol and configuration updates
  • Add models and selectedModel to SystemReadyMessage and model to ChatSendMessage
  • Define SettingsOpenMessage in message types
  • Add claudex.customModel setting definition in package.json
webview/types/messages.ts
package.json

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a 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>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +70 to +75
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';
Copy link

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.

Suggested change
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();

Comment on lines +228 to +229
const newOptions = message.payload.models.slice();
modelState.options = newOptions;
Copy link

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).

Suggested change
const newOptions = message.payload.models.slice();
modelState.options = newOptions;
const newOptions = message.payload.models.slice();
modelState.options.splice(0, modelState.options.length, ...newOptions);

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant