feat: Add LM Studio provider with dynamic model discovery#744
feat: Add LM Studio provider with dynamic model discovery#744athul0rameshan9 wants to merge 6 commits into
Conversation
wyuc
left a comment
There was a problem hiding this comment.
Thanks for this, and welcome — a clean, well-structured first contribution (nice that you covered every locale). A few things to address before merge; two are security-related.
🔴 Server API key can leak to a client-supplied host — app/api/list-models/route.ts
For a server-managed provider configured with only an API key (e.g. OPENAI_API_KEY set, no OPENAI_BASE_URL), resolveBaseUrl() returns undefined, so resolveBaseUrl(...) || clientBaseUrl falls back to the client-supplied baseUrl while resolveApiKey() still returns the server secret. The request then sends Authorization: Bearer <server key> to an arbitrary client-controlled host. For managed providers, please ignore clientBaseUrl entirely and use only the server/default URL when a server key is attached.
🔴 Missing SSRF guard — app/api/list-models/route.ts
The other routes that fetch a client-supplied URL (app/api/generate/voice, azure-voices, generate/video, proxy-media, parse-pdf) all call validateUrlForSSRF() from @/lib/server/ssrf-guard before fetching. This new route fetches after only new URL() parsing, so a crafted baseUrl can make the server probe internal addresses, and the upstream error body is returned to the caller. Please run the same validateUrlForSSRF() before building/fetching modelsUrl. This matters most for hosted / multi-tenant deployments.
🟡 Success-response shape mismatch breaks the feature — components/settings/provider-config-panel.tsx
apiSuccess({ models }) serializes as { success: true, models: [...] } (the helper spreads, it does not nest under data). The client reads data.data?.models, which is always undefined, so even a successful fetch shows the failure message. Read data.models instead.
Once the two security items are addressed the rest looks good. Thanks again for the contribution!
Add LM Studio as a built-in provider and implement a 'Fetch Models' button that queries the /v1/models endpoint to auto-discover available models from any OpenAI-compatible local server (LM Studio, Ollama, etc.). Changes: - Register lmstudio as a built-in provider (localhost:1234/v1, no API key) - Add /api/list-models endpoint to fetch models from OpenAI-compatible APIs - Add 'Fetch Models' button to provider settings for OpenAI-type providers - Add LMSTUDIO_BASE_URL/LMSTUDIO_MODELS env var support - Add i18n translations (en-US, zh-CN) Users no longer need to manually specify models in the env file when using LM Studio - they can discover and select models directly from the app UI.
b8b74a9 to
83fdace
Compare
…fix response shape - Sanitize client inputs for managed providers (ignore client key/baseUrl) to prevent leaking server API keys to attacker-controlled hosts - Add validateUrlForSSRF() check on client-supplied base URLs, matching the pattern used by tts/voice/video routes - Fix response shape: read data.models instead of data.data?.models to match apiSuccess() output format
83fdace to
1ddb0bd
Compare
|
Thanks for the review! All three items have been addressed:
Also rebased onto latest main. Ready for re-review! |
Review:
|
Summary
Add LM Studio as a built-in provider and implement a 'Fetch Models' button that auto-discovers available models from any OpenAI-compatible local server, eliminating the need to manually specify models in the env file.
Related Issues
Fixes #730
Changes
lmstudioas a built-in provider (localhost:1234/v1, no API key required)/api/list-modelsendpoint to fetch models from OpenAI-compatible/v1/modelsAPIsLMSTUDIO_BASE_URL/LMSTUDIO_MODELSenv var support in server provider configType of Change
Verification
tsc --noEmit)