Make the OpenAI LLM provider adapt to OpenAI-compatible servers and reasoning models
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 25/100
Direzione di ricerca
Start in web/pgadmin/llm/providers/openai.py, at _should_use_responses_api (around lines 179-184) and the max_completion_tokens call (line 205), then read client.py around get_llm_client() (line 242). Tests belong in web/pgadmin/llm/tests/test_openai_stream.py, with the Go library's adaptive-parameter scenarios as a reference. Done means the provider adapts token-limit and Responses routing from server errors, caches learned flags per (base_url, model), and handles reasoning-model budgets with bounded retries.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
The OpenAI provider in web/pgadmin/llm/providers/openai.py hard-codes OpenAI's own request conventions, which breaks or degrades it against the OpenAI-compatible servers we tell people to use (LM Studio, LiteLLM, vLLM, EXO, Z.ai's GLM and so on):
- It always sends
max_completion_tokens(line 205), an OpenAI-specific parameter that many compatible servers ignore or reject; they expectmax_tokens. - It switches to the Responses API (
/responses) when an error message happens to contain one of a few substrings (_should_use_responses_api, lines 179-184), including "not a chat model". An unrelated error from a third-party server can therefore move the client onto an endpoint that server doesn't implement, hiding the real failure. - Reasoning models can spend the whole output budget thinking, coming back with empty content and
finish_reason: length. The report pipeline caps output at 500 tokens for planning and 1500 per section (reports/pipeline.py:221and:294), and the resulting error from_raise_max_tokens_errorblames the request size and suggests a larger context window, which is the wrong diagnosis.
Rather than a subclass per vendor (as proposed in #10216), or a check of the hostname against api.openai.com (which would misclassify Azure OpenAI and gateways in front of OpenAI), I'd like the provider to adapt to whatever it is connected to, learning from the server's own responses. pgedge-go-llm-lib 0.4.0 does this already (pgEdge/pgedge-go-llm-lib#43, llm/provider/openai/adapt.go) and is a good reference, tests included.
Proposed design
Token-limit parameter. Send max_tokens by default, since that is what compatible servers understand. If the server rejects it with a 400 whose JSON error has param == "max_tokens" and code == "unsupported_parameter" (as OpenAI's reasoning models do), retry with max_completion_tokens and remember that. Only OpenAI then pays a failed round trip, and only once per model.
Responses API. Replace the substring heuristic with a check on the structured error: reroute to /responses only on a 400 or 404 with no param and a message saying the model is only supported in v1/responses, and remember that too.
Bounded retries. Apply each adjustment at most once per call, and cap the number of sends per call (the Go library uses three), so a chain such as "rerouted, then a parameter rejected" completes without looping.
Remember what was learned across requests. get_llm_client() (client.py:242) builds a new OpenAIClient for every request, so the existing _use_responses_api flag is lost each time. Keep the learned flags in a module-level dict keyed on (base_url, model); pgAdmin is single-process, so in-memory state is sufficient. Log each adjustment once, at debug level.
Reasoning models. Detect that a model reasons from either signal:
usage.completion_tokens_details.reasoning_tokensgreater than zero (OpenAI);- a
reasoning_contentfield on the message or stream delta (Z.ai's GLM, DeepSeek and others).
Once seen, set a "reasoning" flag in the same cache, and have the client multiply the caller's max_tokens (by three, say), so callers such as the report pipeline need no changes. The caps are ceilings, so this costs nothing unless the model uses the extra tokens. On empty content with finish_reason: length, retry once with the larger budget and set the flag, rather than failing straight away; if it is still empty, raise an error that says the output budget was exhausted, not that the request was too large.
Two points to settle during implementation, by testing against real reasoning models: whether three times is enough (GLM-4.7 always thinks, and Z.ai's docs don't say whether reasoning counts against max_tokens), and whether the 500-token planning cap should be raised regardless.
Docker Model Runner. providers/docker.py is a separate 592-line client for what is an OpenAI-compatible API, and also hard-codes max_completion_tokens (line 140). Once the above is in place, it could become a thin subclass that keeps its loopback-only URL validation. This can be a follow-up.
Tidy-ups in the same area. is_available() uses startswith against the default URL (line 100), which also matches a host such as api.openai.com.example.net; compare hostnames instead.
Tests
Port the Go library's adaptive-parameter scenarios into web/pgadmin/llm/tests/test_openai_stream.py, covering both the non-streaming and streaming paths: which token-limit key is sent first and after a rejection; that a custom host never reroutes to /responses on an unrelated error; that learned state survives a new client for the same URL and model; the retry cap; and the reasoning detection and budget scaling, including the empty-response retry.
Documentation
Update the OpenAI-compatible provider lists in docs/en_US/ai_tools.rst and docs/en_US/preferences.rst to include GLM (Z.ai), and say that any non-default host must be added to ALLOWED_LLM_API_URLS by an administrator before pgAdmin will connect to it.
Thanks to @shawonis08, whose work on #10216 diagnosed the underlying problems.
- Lingua principale
- Python
- Stelle
- 3.9k
- Fork
- 910
- Merge medio
- 1g 6h
- PR unite (30g)
- 38
Preparare l'ambiente
- Include un Dockerfile o un file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di pgadmin-org/pgadmin4
-
Feature
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
pgadmin-org/pgadmin4#10426 · 3 commenti · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
Feature
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
pgadmin-org/pgadmin4#10272 · 5 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Feature
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
pgadmin-org/pgadmin4#10157 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Feature
Difficoltà 3/5 1-2 giorni Idoneità per principianti 45/100
pgadmin-org/pgadmin4#10615 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Housekeeping
Difficoltà 5/5 Più di una settimana Idoneità per principianti 12/100
pgadmin-org/pgadmin4#10611 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di pgadmin-org/pgadmin4
Issue simili
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
anchore/grype-db#1149 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
[Bug]: `hermes plugins update` clones an entire monorepo twice - `subdir` is resolved but dropped at both catalog-update call sitesForse già presa @HootRock l’ha presa oggi. Apertacomp/cli P2 type/perf
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
NousResearch/hermes-agent#142417 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
SMC SPEC
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
tenstorrent/tt-oca-harness#3287 ·
I maintainer di solito rispondono entro 1 giorno
-
bug enhancement python
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
DewaldOosthuizen/tech-cheat-sheets-and-notes#392 ·
I maintainer di solito rispondono entro 1 giorno
-
Critical advisories on mainApertasecurity
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
fabriziosalmi/wildbox#801 ·
I maintainer di solito rispondono entro 1 giorno