Skip to content

Support legacy gen_ai token usage attributes#19

Open
haasonsaas wants to merge 1 commit into
raindrop-ai:mainfrom
haasonsaas:codex/legacy-genai-usage-tokens
Open

Support legacy gen_ai token usage attributes#19
haasonsaas wants to merge 1 commit into
raindrop-ai:mainfrom
haasonsaas:codex/legacy-genai-usage-tokens

Conversation

@haasonsaas
Copy link
Copy Markdown
Contributor

@haasonsaas haasonsaas commented May 29, 2026

Summary

Workshop currently drops token counts from the raindrop-ai core-SDK instrumentation path because the producer and consumer disagree on the gen_ai.* token attribute names.

This change teaches parseOtlpRequest to read the legacy OpenLLMetry names in addition to the newer OTel semantic convention names:

  • gen_ai.usage.prompt_tokens
  • gen_ai.usage.completion_tokens

The existing Vercel AI SDK and new-semconv paths stay first in the lookup order, so this is additive for paths that already work.

Root cause

raindrop-ai bundles OpenLLMetry instrumentations such as @traceloop/instrumentation-openai@0.19.0-otel-v1 and the matching Anthropic, Bedrock, Cohere, Vertex, Together, etc. instrumentations. Those emit the legacy token attributes:

gen_ai.usage.prompt_tokens     = 1357
gen_ai.usage.completion_tokens = 82

Workshop ingest only read the newer OTel GenAI semantic convention names for gen_ai.* usage, plus Vercel AI SDK's ai.usage.* attributes:

const inputTokens = first(attrs, "ai.usage.inputTokens", "ai.usage.promptTokens", "ai.usage.prompt_tokens", "gen_ai.usage.input_tokens");
const outputTokens = first(attrs, "ai.usage.outputTokens", "ai.usage.completionTokens", "ai.usage.completion_tokens", "gen_ai.usage.output_tokens");

That means spans from the core-SDK instrumentModules path landed with null / missing input_tokens and output_tokens, so Workshop could not show per-call or per-run token/cost data. The AI SDK path was unaffected because it emits ai.usage.*, which Workshop already handled.

Fix

Append the legacy OpenLLMetry keys to the parser fallback lists:

- "gen_ai.usage.input_tokens")
+ "gen_ai.usage.input_tokens", "gen_ai.usage.prompt_tokens")

- "gen_ai.usage.output_tokens")
+ "gen_ai.usage.output_tokens", "gen_ai.usage.completion_tokens")

first() returns the first attribute that exists, so appending these names preserves the current precedence for AI SDK and new-semconv spans.

Validation

  • Installed dependencies with Bun 1.3.14 using the existing frozen lockfile.
  • bun test tests/ passes locally.
  • bun run build passes locally, including migration embed check, tsc --noEmit, and the Vite UI build.
  • Added tests/parse.test.ts covering the legacy OpenLLMetry attribute pair.

@haasonsaas haasonsaas marked this pull request as ready for review May 29, 2026 03:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant