openai-base: a Responses max_output_tokens cutoff ends as RUN_ERROR without usage instead of finishReason 'length'
Los mantenedores suelen responder en 1 día
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 74/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- typescript
- Área
- backend-api-design
Línea de trabajo
Empieza en packages/openai-base/src/adapters/responses-text.ts y compara el manejo de response.incomplete cerca de las líneas 1748–1806 con la asignación de response.completed cerca de las líneas 2442–2473. Revisa las pruebas del adaptador para los eventos terminales, usage y finish reasons. El trabajo estará terminado cuando los motivos de respuesta incompleta conocidos finalicen con usage y el motivo asignado, mientras que las respuestas fallidas o con un motivo desconocido sigan siendo errores.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
What happens
When a Responses stream hits max_output_tokens, it ends with response.incomplete (status: "incomplete", incomplete_details.reason: "max_output_tokens"), and that event carries the response's usage. The Responses adapter in @tanstack/openai-base turns it into RUN_ERROR (message: "max_output_tokens", code: "incomplete") and drops the usage:
So with the Responses adapter:
- the run ends in
onError, notonFinish, right after the partial text the user has already seen; onUsagenever fires, although the provider billed the tokens;finishReason: 'length'never appears, sountilFinishReason(['length'])and the core stop-on-length path (#1874) never see a capped answer.
The response.completed branch already maps incomplete_details.reason (max_output_tokens → length, content_filter → content_filter), "mirroring the chat-completions adapter". A capped response does not arrive as response.completed, so that mapping is not reached for it:
The Chat Completions adapter reports the same cutoff as RUN_FINISHED with usage and finishReason: 'length'.
Repro
@tanstack/ai 1.0.0, @tanstack/openai-base 1.0.0, @tanstack/ai-vercel-gateway 1.0.0, server-side chat() on Node 24
for await (const chunk of chat({
adapter: createVercelGatewayText('openai/gpt-4.1-nano', key), // Responses API by default
messages: [{ role: 'user', content: 'Count from 1 to 300, separated by commas.' }],
threadId: 'repro',
modelOptions: { max_output_tokens: 16 },
middleware: [{ name: 'probe', onUsage, onFinish, onError }],
})) {
if (chunk.type === 'RUN_FINISHED' || chunk.type === 'RUN_ERROR') console.log(chunk)
}
| Adapter | Terminal chunk | onUsage |
Terminal hook |
|---|---|---|---|
| Responses (default) | RUN_ERROR { message: 'max_output_tokens', code: 'incomplete' } |
not called | onError |
Chat Completions (api: 'chat', max_tokens: 16) |
RUN_FINISHED, usage 19 / 16 |
called once | onFinish, finishReason: 'length' |
On the Responses adapter the chunks arrive as RUN_STARTED, TEXT_MESSAGE_START, TEXT_MESSAGE_CONTENT (62 characters), TEXT_MESSAGE_END, RUN_ERROR. anthropic/claude-sonnet-5.5 gives the same RUN_ERROR. A direct POST https://ai-gateway.vercel.sh/v1/responses with stream: true and max_output_tokens: 16 ends like this for both models (gpt-4.1-nano shown):
{
"type": "response.incomplete",
"response": {
"status": "incomplete",
"incomplete_details": { "reason": "max_output_tokens" },
"usage": { "input_tokens": 19, "output_tokens": 16, "…": "…" }
}
}
The openai SDK types describe response.incomplete as "An event that is emitted when a response finishes as incomplete", with incomplete_details.reason one of max_output_tokens, max_messages, content_filter, steered.
Expected
response.incomplete with incomplete_details.reason max_output_tokens or content_filter ends the run the way the Chat Completions adapter does: RUN_FINISHED with the response's usage and finishReason: 'length' or 'content_filter'. response.failed, and an incomplete response without a known reason, stay RUN_ERROR.
Why
We stop our agent loop with untilFinishReason(['length']) and record usage per model call. On the Responses adapter, a capped answer shows the user an error after a partial answer, and its tokens are not recorded.
- Lenguaje dominante
- TypeScript
- Estrellas
- 3.2k
- Forks
- 372
- Merge medio
- 1 d 14 h
- PR fusionados (30 d)
- 241
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de TanStack/ai
-
Dificultad 3/5 1-2 días Aptitud para principiantes 64/100
TanStack/ai#1926 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 58/100
TanStack/ai#1924 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
ai-vercel-gateway: usage.cost leaves out gateway surcharges, and the BYOK credential type is not exposedPosiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 55/100
Los mantenedores suelen responder en 1 día
-
ai-gemini: native image generation throws "returned no id" when modelOptions.store is falsePosiblemente ocupada @pcbeingused333 la tomó hace 1 día. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 57/100
Los mantenedores suelen responder en 1 día
-
Durable resume through withPersistence never fills ctx.inputResponse for mcp_input interruptsPosiblemente ocupada @tombeckenham la tomó hace 6 días. Abiertowaiting-on: maintainer
TanStack/ai#1885 · 1 asignado ·
Los mantenedores suelen responder en 1 día
Todos los issues de TanStack/ai
Issues similares
-
bug ui-dashboard
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 91/100
caelestia-dots/caelestia#534 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
bug(scripts): install-git-hooks.sh points core.hooksPath at .githooks/, which does not existAbiertoarea: scripts bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
tdk-landscape/tdk-cli-core#2706 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
bobadilla-tech/biasmarket.com#402 ·
Los mantenedores suelen responder en 1 día
-
bug good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
javvadivijayprasad/sel2pw#28 ·