Skip to content

feat: dynamic model loading with provider search#37

Open
raghavdwd wants to merge 3 commits into
mskayyali:mainfrom
raghavdwd:feature/dynamic-models
Open

feat: dynamic model loading with provider search#37
raghavdwd wants to merge 3 commits into
mskayyali:mainfrom
raghavdwd:feature/dynamic-models

Conversation

@raghavdwd
Copy link
Copy Markdown

This pull request enhances the project sidebar and model selection experience, especially around provider/model management and searchability. The main improvements include dynamically fetching available models after entering an API key, adding a search bar to filter models, and refactoring the code for clarity and maintainability.

Enhancements to provider/model selection and settings:

  • Dynamically fetches the latest available models from the selected provider once a valid API key is entered, ensuring users always see up-to-date model options.
  • Adds a search bar to the model dropdown, allowing users to quickly filter and find specific models, which is especially useful when there are many options (e.g., OpenRouter)
  • Updates provider switching logic to use hardcoded models as a fallback and restores saved API keys per provider, improving the user experience when switching between providers.

These changes make it easier for users to manage AI providers and models, streamline the model selection process, and improve the overall codebase quality.

image

Copilot AI review requested due to automatic review settings April 22, 2026 04:48
Copy link
Copy Markdown

Copilot AI left a 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 improves the AI provider/model settings UX in the project sidebar by adding dynamic model loading (based on provider + API key) and a searchable model dropdown, plus some supporting refactors in the AI settings module and README updates.

Changes:

  • Add per-provider modelUrl support and fetch models dynamically with hardcoded fallbacks.
  • Add a model search bar inside the model dropdown in the sidebar settings UI.
  • Update docs to mention dynamic model fetching and model search.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 7 comments.

File Description
lib/ai-settings.ts Adds modelUrl to provider presets and introduces async model fetching + hardcoded fallback helpers; updates settings hook behavior.
components/project-sidebar.tsx Fetches models dynamically in settings UI and adds model search in the dropdown; refactors UI code formatting.
README.md Documents dynamic model fetching and the model dropdown search bar.
Comments suppressed due to low confidence (1)

lib/ai-settings.ts:299

  • loadAIConfig() now looks up the selected model only in the hardcoded lists and falls back to models[0].id when it can’t find s.modelId. With dynamic model loading, this will silently switch users to the first hardcoded model whenever they pick a model not present in AI_MODELS/OPENAI_MODELS/ZAI_MODELS (e.g. most OpenRouter models), causing requests to use a different model than the UI selection. Preserve s.modelId when it’s not in the hardcoded list, and only normalize IDs for the specific provider-switch case (like stripping an openai/ prefix when provider is openai).
  const models = getHardcodedModelsForProvider(s.provider)
  const model = models.find(m => m.id === s.modelId)
  // Use the matched model's id if found; otherwise fall back to the first model
  // for this provider.  This handles the case where localStorage still holds an
  // OpenRouter-prefixed id (e.g. "openai/gpt-4o") after switching to OpenAI —
  // that string won't match any entry in OPENAI_MODELS so we fall back to "gpt-4o".
  const modelId = model?.id ?? models[0]?.id ?? s.modelId ?? DEFAULT_MODEL_ID
  // Z.ai does not support grounding; only openrouter and openai do
  const supportsGrounding =
    (s.provider === "openrouter" || s.provider === "openai") &&
    s.webGrounding &&
    (model?.supportsGrounding ?? false)
  return { apiKey: s.apiKey, modelId, supportsGrounding, provider: s.provider, customBaseUrl: s.customBaseUrl }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread components/project-sidebar.tsx
Comment thread components/project-sidebar.tsx
Comment on lines 491 to 512
{/* Model Selector */}
<div className="flex flex-col gap-2">
<label className="font-mono text-[9px] font-bold uppercase tracking-[0.2em] text-muted-foreground">
Model
</label>
{models.length === 0 ? (
<div className="flex items-center gap-2 rounded-md border border-white/10 bg-white/[0.04] px-2.5 py-2 focus-within:border-primary/50 transition-colors">
<input
type="text"
value={draft.modelId}
onChange={e => setDraft(d => ({ ...d, modelId: e.target.value }))}
onChange={(e) =>
setDraft((d) => ({ ...d, modelId: e.target.value }))
}
placeholder="e.g. gpt-4o, claude-3-opus-20240229"
className="flex-1 bg-transparent font-mono text-[11px] text-foreground outline-none placeholder:text-muted-foreground/40"
autoComplete="off"
spellCheck={false}
/>
</div>
) : (
<div className="relative">
<button
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because models always falls back to getHardcodedModelsForProvider(draft.provider) when dynamic loading returns an empty list, models.length === 0 is effectively unreachable (the hardcoded lists are non-empty). This removes the UI path for manually entering a custom modelId, which is important when customBaseUrl points at an OpenAI-compatible endpoint with its own model names. Consider always providing a “Custom model…” option or keeping a text input available even when the dropdown is populated.

Copilot uses AI. Check for mistakes.
Comment thread README.md
Comment thread lib/ai-settings.ts
Comment thread lib/ai-settings.ts
Comment thread components/project-sidebar.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants