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

@tanstack/openai-base: Responses usage drops input_tokens_details.cache_write_tokens

Abierto
#1,734 0 comentarios 0 reacciones 1 asignado Ver en GitHub

Los mantenedores suelen responder en 1 día

@tombeckenham ya está trabajando en esto.

Desde el 13/10/2026.

Evaluación

Este issue todavía no se ha evaluado.

Descripción

waiting-on: maintainer

Package / version: @tanstack/openai-base 0.13.1 via @tanstack/ai-openai 0.29.1, @tanstack/ai 0.68.0, openai 7.32.0, Node 24.20.0. The same code is on main.

Summary

buildResponsesUsage in packages/openai-base/src/usage.ts reads input_tokens_details.cached_tokens and ignores input_tokens_details.cache_write_tokens. A Responses API call that writes the prompt cache reports the written count, and OpenAI prices cache writes separately from uncached input on current models, but the number never reaches TokenUsage.promptTokensDetails.cacheWriteTokens. Anything that meters spend from usage under-counts every call that primes a cache.

buildChatCompletionsUsage in the same file already maps the field (prompt_tokens_details.cache_write_tokens → cacheWriteTokens), so the two paths disagree. The openai SDK types cache_write_tokens as a required member of ResponseUsage.input_tokens_details.

Reproduction

import { chat } from '@tanstack/ai'
import { createOpenaiChat } from '@tanstack/ai-openai'
import OpenAI from 'openai'

const MODEL = 'gpt-6-luna'
// A system prompt past the 1024-token caching floor. A fresh nonce makes each prompt a first
// sighting, so the call writes the cache instead of reading it.
const filler = 'The quarterly report covers revenue, margin, churn, headcount, and regional growth across every business unit. '
const fresh = () => `You answer in one word. Session ${crypto.randomUUID()}.\n\n${filler.repeat(90)}`
const question = 'What colour is the sky on a clear day?'

const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })
const raw = await client.responses.create({ model: MODEL, instructions: fresh(), input: question })
console.log('raw Responses usage, fresh prompt =', JSON.stringify(raw.usage))

const adapter = createOpenaiChat(MODEL, process.env.OPENAI_API_KEY)
for await (const c of chat({ adapter, systemPrompts: [fresh()], messages: [{ role: 'user', content: question }] })) {
  if (c.type === 'RUN_FINISHED') console.log('RUN_FINISHED usage, fresh prompt =', JSON.stringify(c.usage))
}

Observed

raw Responses usage, fresh prompt = {"input_tokens":1941,"input_tokens_details":{"cache_write_tokens":1938,"cached_tokens":0},"output_tokens":5,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":1946}
RUN_FINISHED usage, fresh prompt = {"promptTokens":1944,"completionTokens":18,"totalTokens":1962,"completionTokensDetails":{"reasoningTokens":11}}

OpenAI reports 1938 tokens written to the cache. The RUN_FINISHED usage has no promptTokensDetails at all.

A second call with the same prompt comes back with cached_tokens: 1914 and the adapter does surface that one as promptTokensDetails.cachedTokens, so only the write side is missing.

Expected

usage.promptTokensDetails.cacheWriteTokens equal to input_tokens_details.cache_write_tokens, as the Chat Completions path does.

Cause and fix

buildResponsesUsage only copies cached_tokens (packages/openai-base/src/usage.ts, around line 111 on main). I'm carrying this as a local patch to the built file, the same shape as the cachedTokens block above it, in case it saves whoever picks this up a minute:

const cacheWriteTokens = usage.input_tokens_details?.cache_write_tokens
if (cacheWriteTokens && cacheWriteTokens > 0) {
  result.promptTokensDetails = {
    ...result.promptTokensDetails,
    cacheWriteTokens,
  }
}

Do you intend to try to help solve this bug with your own PR? No, because I do not have time to dig into it. The hunk above is the fix as far as I can tell; I won't be sending a PR.

  • I agree to follow this project's Code of Conduct
  • I understand that if my bug cannot be reliably reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.
Lenguaje dominante
TypeScript
Estrellas
3.2k
Forks
361
Merge medio
1 d 15 h
PR fusionados (30 d)
221

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 TanStack/ai

Todos los issues de TanStack/ai

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.