Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Make the OpenAI LLM provider adapt to OpenAI-compatible servers and reasoning models

Abierto
#10,570 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@MaybeSomeone-arc18 ya está trabajando en esto.

Desde el 17/10/2026.

  • #10636 de @MaybeSomeone-arc18 — abierto

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
25/100
Tipo de issue
Refactorización
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
python
Área
backend

Línea de trabajo

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.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Bug

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 expect max_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:221 and :294), and the resulting error from _raise_max_tokens_error blames 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_tokens greater than zero (OpenAI);
  • a reasoning_content field 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.

Lenguaje dominante
Python
Estrellas
3.9k
Forks
908
Merge medio
1 d 6 h
PR fusionados (30 d)
38

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de pgadmin-org/pgadmin4

Todos los issues de pgadmin-org/pgadmin4

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.