Skip to content

Neuer OpenAI-kompatibler Provider mit eigener Basis-URL - #9

Open
skerbis wants to merge 2 commits into
mainfrom
fix/ollama-api-key-passthrough
Open

Neuer OpenAI-kompatibler Provider mit eigener Basis-URL#9
skerbis wants to merge 2 commits into
mainfrom
fix/ollama-api-key-passthrough

Conversation

@skerbis

@skerbis skerbis commented Aug 30, 2026

Copy link
Copy Markdown
Member

Hintergrund

Ich betreibe einen selbstgehosteten KI-Server (Open WebUI vor Ollama), extern erreichbar und per Bearer-Token abgesichert. Weder der bestehende "OpenAI"-Provider (fest auf api.openai.com verdrahtet, kein Basis-URL-Override, zielt zudem auf die neuere /v1/responses-API) noch "Ollama" (natives /api/chat-Protokoll) funktionieren gegen einen solchen Server – nur dessen klassische OpenAI-Chat-Completions-kompatible API unter /v1/... ist erreichbar. Das betrifft nicht nur Open WebUI, sondern auch LiteLLM, vLLM, LM Studio, text-generation-webui und ähnliche Setups – ein häufiger Anwendungsfall beim Selbsthosten.

Änderungen

  • Neuer Provider "OpenAI-kompatibel": eigene Basis-URL + optionaler API-Key als Bearer-Token, sendet an {base_url}/chat/completions, liest choices[0].message.content. Neue Klassen unter lib/Bridge/OpenAiCompatible/ (ModelClient, ResultConverter, ModelCatalog – akzeptiert beliebige Modellnamen, kein fester Katalog wie bei Ollama nötig, da selbstgehostete Server beliebige Modellnamen haben können).
  • Wiederverwendet Symfony AIs Contract::create() ohne zusätzliche Normalizer – die Basis-Normalizer für Nachrichten/Bilder erzeugen bereits exakt das klassische {messages:[...], model}- bzw. {type:"image_url", image_url:{url:...}}-Format, keine eigene Contract-Klasse nötig.
  • Enthält zusätzlich den Ollama-API-Key-Fix aus dem vorherigen, jetzt geschlossenen PR (Service::getPlatform() gab den API-Key nie an OllamaFactory::create() weiter, obwohl die Bibliothek das unterstützt; Feld war für Ollama in der UI zudem ausgeblendet).
  • vendor/composer/autoload_{classmap,static}.php per composer dump-autoload -o neu erzeugt (laut CLAUDE.md dieses Repos der dokumentierte Workflow nach Klassen-Änderungen in lib/).

Testplan

  • php -l auf allen geänderten/neuen PHP-Dateien
  • node --check assets/profiles.js
  • Manuell, gegen den echten Open-WebUI-Server: direkter curl-Test von POST /v1/chat/completions mit Bearer-Token bestätigt Antwort vom Modell (HTTP 200, echter Content) – das native Ollama-/api/chat liefert dort dagegen nur die Weboberfläche/405.
  • Manuell über die REDAXO-Oberfläche: Profil mit Provider "OpenAI-kompatibel" anlegen, Basis-URL + API-Key eintragen, "Verbindung testen" nutzen.

🤖 Generated with Claude Code

skerbis and others added 2 commits August 30, 2026 15:32
Service::getPlatform() built the Ollama platform from base_url only,
even though the profile's api_key column exists and Symfony AI's
Ollama\PlatformFactory::create() already accepts an optional API key
as its second argument (applied as auth_bearer on the HTTP client).
This made it impossible to point a profile at an externally reachable
or reverse-proxy-secured Ollama server.

Now passes the stored api_key through (empty string treated as none,
same as an unsecured local instance). Unhides the API key field for
Ollama in the profile form and clarifies both language files.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Neither the existing "openai" provider (hardcoded to api.openai.com,
no base_url override, and targets the newer /v1/responses API) nor
"ollama" (native Ollama /api/chat protocol) work against self-hosted
gateways that only expose the classic OpenAI Chat Completions API
(Open WebUI, LiteLLM, vLLM, LM Studio, text-generation-webui, ...).

Adds a new "openai_compatible" provider: custom base_url + optional
Bearer token, POSTs to {base_url}/chat/completions, parses
choices[0].message.content. Reuses Symfony AI's Contract::create()
without additional normalizers — the base message/image normalizers
already produce the classic {messages:[...], model} / {type:
"image_url", image_url:{url:...}} shape needed here, so no custom
Contract subclass or payload building was necessary; only a
ModelClient, ResultConverter and ModelCatalog (accepts any model
name, no fixed catalog) were added under lib/Bridge/OpenAiCompatible.

Also includes the Ollama API-key passthrough fix from the previous,
now-superseded PR (Service::getPlatform() never forwarded api_key to
OllamaFactory::create(), even though it accepts one; the field was
also hidden for Ollama in the profile form).

vendor/composer/autoload_{classmap,static}.php regenerated via
`composer dump-autoload -o` per this repo's documented workflow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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