Summary
The Google GenAI Java SDK (com.google.genai, v1.18.0, the version this module targets) exposes Models.generateVideos(...) (Veo video-generation models) and the associated long-running-operation polling API (client.operations.getVideosOperation(...)). Braintrust's Java GenAI instrumentation intercepts these calls only incidentally, through a generic HTTP-transport hook that was designed for generateContent. The result is spans that are silently mislabeled and largely empty for video generation — not a total absence of spans, but instrumentation with materially less detail/fidelity than the documented generate_content path.
What is missing
BraintrustApiClient (braintrust-sdk/instrumentation/genai_1_18_0/src/main/java/com/google/genai/BraintrustApiClient.java) intercepts every HTTP call made by the SDK by overriding the transport-level methods on ApiClient:
request(String, String, String, Optional<HttpOptions>) — line 186
request(String, String, byte[], Optional<HttpOptions>) — line 210
asyncRequest(String, String, String, Optional<HttpOptions>) — line 239
asyncRequest(String, String, byte[], Optional<HttpOptions>) — line 277
Because this hook is transport-level, a generateVideos call (and each operations.getVideosOperation poll of the resulting long-running operation) does produce a span — but tagSpan (lines 50–161) was written exclusively for the generateContent request/response shape:
- Line 156 unconditionally sets
braintrust.span_attributes to {"type": "llm"} for every call this client makes, including video-generation calls, which are not LLM chat-completion calls.
- Lines 65–76 and 81–95 only promote
model/systemInstruction/tools/toolConfig/safetySettings/cachedContent and generationConfig.{temperature,topP,topK,candidateCount,maxOutputTokens,stopSequences,responseMimeType,responseSchema} into braintrust.metadata/input_json. generateVideos requests use an entirely different shape (instances/parameters or prompt/image/video + a GenerateVideosConfig with fields like numberOfVideos, durationSeconds, aspectRatio, enhancePrompt, personGeneration) — none of these fields are extracted, so input_json for a video-generation span is effectively empty.
- Lines 127–149 only look for
usageMetadata.{promptTokenCount,candidatesTokenCount,totalTokenCount,cachedContentTokenCount} to populate braintrust.metrics. Video-generation responses have no such field, so metrics are silently skipped (not wrong, just absent) while the span is still tagged type: llm.
generateVideos returns a GenerateVideosOperation that is not done immediately; the caller polls client.operations.getVideosOperation(...) repeatedly until completion. Each poll produces its own disconnected span (named via URL-derived getOperation, e.g. get_videos_operation) rather than being correlated to the originating video-generation request — there is no long-running-operation span model, unlike the single request/response span Braintrust produces for generate_content.
There is no reference anywhere in this module (or its tests) to generateVideos, GenerateVideosOperation, GenerateVideosConfig, Veo, or getVideosOperation — confirmed via full-directory grep of braintrust-sdk/instrumentation/genai_1_18_0/.
Braintrust docs status
Checked https://www.braintrust.dev/docs/integrations/ai-providers/gemini (current as of this audit):
- Java section documents only content-generation spans (
generate_content, sync/async) and generateContentStream, with request metadata (model, contents, generation config), response, and token metrics.
- No mention of video generation,
generateVideos, or Veo models for any language (Java, Python, TypeScript, Go).
- Status: not_found — video generation tracing is undocumented for Java (and for every other language) in the current docs.
Upstream sources
- Google GenAI Java SDK repo: https://github.com/googleapis/java-genai —
Models class exposes generateVideos(String model, GenerateVideosSource source, GenerateVideosConfig config) and generateVideos(String model, String prompt, Image image, Video video, GenerateVideosConfig config).
- SDK README usage example (video generation via Veo, polling
operation.done() / client.operations.getVideosOperation): https://github.com/googleapis/java-genai/blob/main/README.md
- SDK CHANGELOG entries for video generation support (e.g. "Add backwards compatibility for generateVideos in Java SDK", "Add support for Veo frame interpolation and video extension"): https://github.com/googleapis/java-genai/blob/main/CHANGELOG.md
- Gemini API Veo docs (request/response/config shape —
GenerateVideosConfig fields like numberOfVideos, durationSeconds, aspectRatio): https://ai.google.dev/gemini-api/docs/veo
- Java Veo 3 walkthrough (async polling pattern): https://glaforge.dev/posts/2025/09/10/generating-videos-in-java-with-veo3/
Local files inspected
braintrust-sdk/instrumentation/genai_1_18_0/src/main/java/com/google/genai/BraintrustApiClient.java — full file read; tagSpan (lines 50–161) and the four transport overrides (lines 186, 210, 239, 277) are the only interception points, and are generateContent-shaped.
braintrust-sdk/instrumentation/genai_1_18_0/src/test/java/dev/braintrust/instrumentation/genai/v1_18_0/BraintrustGenAITest.java — only tests sync generateContent; no video-generation test coverage.
- Full-directory grep of
braintrust-sdk/instrumentation/genai_1_18_0/ for generateImages|GenerateImages|predictLongRunning|generate_videos|video — zero matches.
Summary
The Google GenAI Java SDK (
com.google.genai, v1.18.0, the version this module targets) exposesModels.generateVideos(...)(Veo video-generation models) and the associated long-running-operation polling API (client.operations.getVideosOperation(...)). Braintrust's Java GenAI instrumentation intercepts these calls only incidentally, through a generic HTTP-transport hook that was designed forgenerateContent. The result is spans that are silently mislabeled and largely empty for video generation — not a total absence of spans, but instrumentation with materially less detail/fidelity than the documentedgenerate_contentpath.What is missing
BraintrustApiClient(braintrust-sdk/instrumentation/genai_1_18_0/src/main/java/com/google/genai/BraintrustApiClient.java) intercepts every HTTP call made by the SDK by overriding the transport-level methods onApiClient:request(String, String, String, Optional<HttpOptions>)— line 186request(String, String, byte[], Optional<HttpOptions>)— line 210asyncRequest(String, String, String, Optional<HttpOptions>)— line 239asyncRequest(String, String, byte[], Optional<HttpOptions>)— line 277Because this hook is transport-level, a
generateVideoscall (and eachoperations.getVideosOperationpoll of the resulting long-running operation) does produce a span — buttagSpan(lines 50–161) was written exclusively for thegenerateContentrequest/response shape:braintrust.span_attributesto{"type": "llm"}for every call this client makes, including video-generation calls, which are not LLM chat-completion calls.model/systemInstruction/tools/toolConfig/safetySettings/cachedContentandgenerationConfig.{temperature,topP,topK,candidateCount,maxOutputTokens,stopSequences,responseMimeType,responseSchema}intobraintrust.metadata/input_json.generateVideosrequests use an entirely different shape (instances/parametersorprompt/image/video+ aGenerateVideosConfigwith fields likenumberOfVideos,durationSeconds,aspectRatio,enhancePrompt,personGeneration) — none of these fields are extracted, soinput_jsonfor a video-generation span is effectively empty.usageMetadata.{promptTokenCount,candidatesTokenCount,totalTokenCount,cachedContentTokenCount}to populatebraintrust.metrics. Video-generation responses have no such field, so metrics are silently skipped (not wrong, just absent) while the span is still taggedtype: llm.generateVideosreturns aGenerateVideosOperationthat is notdoneimmediately; the caller pollsclient.operations.getVideosOperation(...)repeatedly until completion. Each poll produces its own disconnected span (named via URL-derivedgetOperation, e.g.get_videos_operation) rather than being correlated to the originating video-generation request — there is no long-running-operation span model, unlike the single request/response span Braintrust produces forgenerate_content.There is no reference anywhere in this module (or its tests) to
generateVideos,GenerateVideosOperation,GenerateVideosConfig,Veo, orgetVideosOperation— confirmed via full-directory grep ofbraintrust-sdk/instrumentation/genai_1_18_0/.Braintrust docs status
Checked https://www.braintrust.dev/docs/integrations/ai-providers/gemini (current as of this audit):
generate_content, sync/async) andgenerateContentStream, with request metadata (model, contents, generation config), response, and token metrics.generateVideos, or Veo models for any language (Java, Python, TypeScript, Go).Upstream sources
Modelsclass exposesgenerateVideos(String model, GenerateVideosSource source, GenerateVideosConfig config)andgenerateVideos(String model, String prompt, Image image, Video video, GenerateVideosConfig config).operation.done()/client.operations.getVideosOperation): https://github.com/googleapis/java-genai/blob/main/README.mdGenerateVideosConfigfields likenumberOfVideos,durationSeconds,aspectRatio): https://ai.google.dev/gemini-api/docs/veoLocal files inspected
braintrust-sdk/instrumentation/genai_1_18_0/src/main/java/com/google/genai/BraintrustApiClient.java— full file read;tagSpan(lines 50–161) and the four transport overrides (lines 186, 210, 239, 277) are the only interception points, and are generateContent-shaped.braintrust-sdk/instrumentation/genai_1_18_0/src/test/java/dev/braintrust/instrumentation/genai/v1_18_0/BraintrustGenAITest.java— only tests syncgenerateContent; no video-generation test coverage.braintrust-sdk/instrumentation/genai_1_18_0/forgenerateImages|GenerateImages|predictLongRunning|generate_videos|video— zero matches.