Skip to content

Add selectable OpenAI-compatible local provider - #80

Open
bmxmarine wants to merge 2 commits into
BlackMixture:mainfrom
bmxmarine:feat/openai-compatible-provider
Open

bmxmarine wants to merge 2 commits into
BlackMixture:mainfrom
bmxmarine:feat/openai-compatible-provider

Conversation

@bmxmarine

@bmxmarine bmxmarine commented Sep 28, 2026 •

Copy link
Copy Markdown

Add selectable OpenAI-compatible local provider

What

Adds a new selectable OpenAI-compatible local provider to the External LLM / prompt-AI settings, so Mix Studio can talk to any server that exposes the OpenAI Chat Completions API (/v1/chat/completions) — vLLM, llama.cpp server, Ollama /v1, text-generation-webui, etc.

Also includes a small defensive guard so a Library card click can't be killed by a missing resetLibrarySplat definition (see second commit).

Why

Users running local inference through OpenAI-compatible servers (not just ComfyUI/Ollama/LM Studio) had no first-class provider option. This wires that path through the existing local-provider plumbing without adding dependencies, keeping the server zero-dependency and the frontend build-free per CONTRIBUTING.md.

The guard commit is hardening only: in a clean clone resetLibrarySplat is defined in splat-workspace.js and the click works. The guard prevents a dead click when that script is stale/missing on a partial deploy or stale service-worker cache.

How

  • lib/external-llm.js — register openai-compatible provider, modeled on lmstudio (OpenAI Chat Completions format); optional Authorization: Bearer <key> header, omitted when no key configured; transcription via /v1/audio/transcriptions (whisper-1 default).
  • server.js — route chat + voice transcription through the new provider; treat as local for grouping/longer timeouts.
  • public/index.html — provider dropdown option + settings fields (base URL, model, transcription model, optional API key).
  • public/app.js — UI wiring (mode classifier, settings apply/payload, clear-key, toggle). Guard commit: typeof check on both resetLibrarySplat() call sites (openLightbox, closeLightbox).
  • test/external-llm.test.js, test/local-prompt-ai-ui.test.js — tests for provider registration, routing, transcription, label-aware toggle, temperature-0 under schema, and the forced-tool-call path.

Testing

  • node --check server.js public/app.js lib/external-llm.js — clean
  • node --test — 1339 pass / 0 fail
  • Live mock round-trip: chat with auth, chat keyless, audio transcription — all passed
  • Browser check: Library card click opens preview (guard verified live)
  • Manual against a real OpenAI-compatible endpoint (vLLM / llama.cpp / Ollama /v1) — needs a live server

Checklist

  • Tests pass
  • No console errors
  • No new dependencies (server stays zero-dependency, frontend build-free)
  • New logic in focused lib/ module with tests
  • No destructive routes tested against real data/

Commits

  1. feat(external-llm): add selectable OpenAI-compatible local provider
  2. fix(library): guard resetLibrarySplat call against missing definition

Register an openai-compatible provider modeled on the existing local
providers (OpenAI Chat Completions format) so any server exposing
/v1/chat/completions works: vLLM, llama.cpp server, Ollama /v1,
text-generation-webui, etc.

- treat it as a local provider for UI grouping, longer timeouts, optional API key
- add provider UI fields (base URL, model, transcription model, optional key)
- route chat and voice transcription through the new provider
- add tests for provider registration, routing, and transcription
openLightbox and closeLightbox call resetLibrarySplat(), which is
defined in splat-workspace.js. If that script is stale or missing on a
partial deploy, the call throws a ReferenceError and aborts before the
lightbox shows, so clicking a Library card does nothing.

Guard both call sites with a typeof check so the preview opens normally
even when splat-workspace.js has not loaded. No behavior change when the
function is present.

This branch has not been deployed

No deployments
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.

1 participant