[bot] OpenAI Images API spans missing input/output capture
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 68/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bien especificado
- Estado de actividad
- Tranquilo
- Stack tecnológico
- java
- Área
- api, observability
Línea de trabajo
Comienza en braintrust-sdk/src/main/java/dev/braintrust/instrumentation/InstrumentationSemConv.java leyendo tagOpenAIRequest(), tagOpenAIResponse() y getSpanName(), y después inspecciona los fixtures de cassette existentes de OpenAI chat_completions y responses. Añade cobertura de Images API para las llamadas generate, edit y variation; se considera terminado cuando los spans capturan los datos documentados de la solicitud y la respuesta de imagen, el uso cuando corresponda y un nombre de span legible para las personas, con tests o fixtures que cubran este comportamiento.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
The OpenAI instrumentation intercepts every HTTP call made through the OpenAI Java client's HttpClient (generic, transport-level wrapping), so calls to the Images API (client.images().generate(), .edit(), .createVariation()) do produce a span. However, InstrumentationSemConv's request/response tagging logic only recognizes the Chat Completions (messages/choices) and Responses API (input/output) JSON shapes. Images API requests and responses use neither shape, so the resulting spans have no useful input or output data — the same class of gap already fixed/tracked for embeddings (#66) and audio (#131), but not yet filed for Images.
What is missing
InstrumentationSemConv.tagOpenAIRequest() (lines 127–138 of braintrust-sdk/src/main/java/dev/braintrust/instrumentation/InstrumentationSemConv.java):
if (requestJson.has("messages")) {
span.setAttribute("braintrust.input_json", toJson(requestJson.get("messages")));
} else if (requestJson.has("input") && requestJson.get("input").isArray()) {
span.setAttribute("braintrust.input_json", toJson(requestJson.get("input")));
}
An images.generate request body looks like:
{
"model": "gpt-image-1",
"prompt": "A photorealistic cat sitting on a moon",
"size": "1024x1024",
"quality": "high",
"n": 1
}
prompt is a plain string (not messages, not an input array), so neither branch matches — braintrust.input_json is never set for Images API calls. size, quality, n, and style are also dropped since only model is captured into metadata.
InstrumentationSemConv.tagOpenAIResponse() (lines 144–201) only sets braintrust.output_json when the response has choices or output:
if (responseJson.has("choices")) {
span.setAttribute("braintrust.output_json", toJson(responseJson.get("choices")));
} else if (responseJson.has("output")) {
span.setAttribute("braintrust.output_json", toJson(responseJson.get("output")));
}
An images.generate response returns {"data": [{"url": "...", "revised_prompt": "..."}], ...} (or b64_json instead of url). Neither choices nor output is present, so braintrust.output_json is never set — the generated image URL/base64 data and revised_prompt are silently dropped. No usage extraction exists for the Images API's token-based billing on gpt-image-1 either.
The span name mapping in getSpanName() (lines 511–522) also has no case for the images/generations / images/edits / images/variations path segments, so the span name falls back to the raw last path segment instead of a human-readable name like the existing "Chat Completion"/"Embeddings" cases.
Braintrust docs status
- not_found — the Braintrust OpenAI integration docs at https://www.braintrust.dev/docs/integrations/ai-providers/openai document streaming audio transcription tracing ("Braintrust traces streaming audio transcription calls for sync and async OpenAI clients") but make no mention of the Images API or image generation tracing for any language.
Upstream sources
- OpenAI Images API reference: https://platform.openai.com/docs/api-reference/images/create — documents
prompt(string, required),size,quality,n,style,response_format, and the responsedata[]array withurl/b64_json/revised_prompt - OpenAI Java SDK:
client.images().generate(ImageGenerateParams),.edit(ImageEditParams),.createVariation(ImageCreateVariationParams)— stable, documented methods oncom.openai:openai-java(this repo pins2.15.0,)) - gpt-image-1 token-based usage: https://platform.openai.com/docs/guides/image-generation —
gpt-image-1responses include ausageobject withinput_tokens/output_tokens, distinct from the legacy DALL·E per-image pricing
Local files inspected
braintrust-sdk/src/main/java/dev/braintrust/instrumentation/InstrumentationSemConv.java— lines 110–141 (tagOpenAIRequest: onlymessages/array-inputhandled), lines 143–201 (tagOpenAIResponse: onlychoices/outputhandled), lines 511–522 (getSpanName: no case forimages/*paths)braintrust-sdk/instrumentation/openai_2_15_0/src/main/java/dev/braintrust/instrumentation/openai/v2_15_0/TracingHttpClient.java— generic HTTP-level wrapping; delegates all tagging toInstrumentationSemConvtest-harness/src/testFixtures/resources/cassettes/openai/mappings/— onlychat_completions-*andresponses-*cassette files exist; noimages-*cassette or test exists anywhere in the repo (confirmed via repo-wide search)
- Lenguaje dominante
- Java
- Estrellas
- 21
- Forks
- 5
- Merge medio
- 2 d 7 h
- PR fusionados (30 d)
- 8
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 braintrustdata/braintrust-sdk-java
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
Todos los issues de braintrustdata/braintrust-sdk-java
Issues similares
-
executions.Query — startDate and timeRange filters are sent with inverted comparison operators Abiertoarea/plugin
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
kestra-io/plugin-kestra#190 ·
-
litertlm-android AAR ships no consumer ProGuard rules → "mid == null" SIGABRT in minified apps Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
google-ai-edge/LiteRT-LM#3739 ·
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
-
Add canonical URLs and a sitemap Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
integra-team-red/meet-map#249 ·
-
[Studio][Bug] Cancelled create-user dialog keeps the password and admin switch for the next attempt Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
apache/rocketmq-dashboard#5064 ·