Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

/v1/responses reports usage.output_tokens_details.reasoning_tokens = 0 even when the reply has reasoning

Aperta
#717 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
Mezza giornata
Idoneità per principianti
62/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
python
Ambito
api, backend

Direzione di ricerca

Start with _usage() in python/freetoken/server/responses_api.py (around lines 481-490), which hard-codes reasoning_tokens=0 for every Responses usage object. Then read GenResult and GenDone in python/freetoken/server/generation.py and the reasoning-parser state near lines 389-422, since the count has to be taken there. Done means output_tokens_details.reasoning_tokens is non-zero for a reply with reasoning, including truncated replies, and stays 0 with thinking off.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

What happened

With thinking on, /v1/responses returns a reasoning output item holding the full trace, but usage.output_tokens_details.reasoning_tokens is always 0, both non-streaming and in the streamed terminal events. A client that budgets or reports from this field is told no reasoning happened. When max_output_tokens cuts a reply off, the client cannot tell from usage how much of the budget the reasoning used. /v1/chat/completions has no completion_tokens_details at all, so it gives no count either (#307 and a comment on #302 mention this in passing).

Minimal reproduction

PYTHONPATH=python python -c "
from freetoken.server.generation import GenResult
from freetoken.server.responses_api import build_responses_response, ResponsesRequest
req = ResponsesRequest(model='m', input='hi')
r = GenResult(reasoning='Let me think about this carefully. '*20, content='4', tool_calls=[],
              finish_reason='stop', prompt_tokens=12, completion_tokens=180)
u = build_responses_response(r, req, 'resp_1', 0).usage
print('output_tokens', u.output_tokens, 'reasoning_tokens', u.output_tokens_details.reasoning_tokens)
"
output_tokens 180 reasoning_tokens 0
Cause (current main, 9b68e007)
  • python/freetoken/server/responses_api.py:481-490: _usage() hard-codes OutputTokensDetails(reasoning_tokens=0). Every Responses usage object is built by it: the non-stream builder (:452) and the stream's response.incomplete / response.completed / response.failed events (:717, :726, :739, :754).
  • Nothing on the generation path counts reasoning tokens. GenDone (python/freetoken/server/generation.py:112) and GenResult (:124-132) carry only prompt_tokens/completion_tokens, and openai_api.py:637-646 _usage() has no completion_tokens_details.
Proposed fix

Count reasoning tokens once in the generation path, carry the count on GenResult/GenDone, and report it as output_tokens_details.reasoning_tokens (Responses) and completion_tokens_details.reasoning_tokens (chat completions). The counter could start in the same state as the reasoning parser (force_reasoning, generation.py:389-422), so that a template that pre-opens <think> is counted from the first token. It would stop at the think-end token. If generation ends before that token, all completion tokens would count as reasoning, so a reply truncated mid-reasoning reports its real count rather than 0. With no reasoning parser, or thinking off, the count stays 0.

Environment

Seen serving nvidia/Qwen3.8-Flash-Next-NVFP4 on an RTX 5080 16 GB; the reproduction above is CPU-only on main 9b68e007.

Lingua principale
Python
Stelle
14.2k
Fork
1.4k
Merge medio
23h 57m
PR unite (30g)
92

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di FlashML-org/FreeToken

Tutte le issue di FlashML-org/FreeToken

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.