Skip to content

CAMEL-24560: Use Long for GenAiUsage token counts - #26105

Merged
davsclaus merged 2 commits into
apache:mainfrom
atiaomar1978-hub:feature/CAMEL-24560-genai-usage-long-tokens-c587
Sep 4, 2026
Merged

CAMEL-24560: Use Long for GenAiUsage token counts#26105
davsclaus merged 2 commits into
apache:mainfrom
atiaomar1978-hub:feature/CAMEL-24560-genai-usage-long-tokens-c587

Conversation

@atiaomar1978-hub

Copy link
Copy Markdown
Contributor

Summary

Changes GenAiUsage token fields from Integer to Long so OpenAI and other providers that report long token counts are recorded without lossy (int) casts or Math.toIntExact failures.

Follow-up to CAMEL-23861 / review on PR #25337.

Changes

  • GenAiUsage: inputTokens and outputTokens are now Long; primary factory accepts Long; convenience overload keeps Integer for LangChain4j/Spring AI call sites
  • OpenAIProducer: passes usage.promptTokens() / usage.completionTokens() directly (removed toTokenCount helper)
  • OpenAIEmbeddingsProducer: sets prompt/total token headers as long (no (int) cast)
  • GenAiMicrometerSupport: records token counters with increment(double) for large values
  • Tests: GenAiUsageTest plus large-token, null/zero, and span coverage
  • Upgrade guide: note that GenAiUsage uses Long token fields

Testing

./mvnw -pl components/camel-ai/camel-ai-observability-api,components/camel-ai/camel-ai-observability -am test \
  -Dtest=GenAiUsageTest,GenAiObservabilityTest,GenAiObservabilitySpanTest

Review notes (Bugbot + Grok)

  • Fixed embeddings producer header truncation flagged by Bugbot
  • Added null/zero Micrometer counter guard test per Grok review

AI-generated PR description on behalf of atiaomar1978-hub

cursoragent and others added 2 commits September 4, 2026 02:40
OpenAI token usage returns long values; storing them as Integer required
Math.toIntExact casts that could overflow or fail for large counts.

- Change GenAiUsage inputTokens/outputTokens to Long
- Keep Integer factory overload for LangChain4j/Spring AI call sites
- Record large token values in Micrometer counters via increment(double)
- Pass OpenAI prompt/completion token counts without int conversion
- Add GenAiUsageTest and large-token observability coverage
- Document Long token fields in the 4.23 upgrade guide

Co-authored-by: Cursor Agent <noreply@cursor.com>
- Stop narrowing OpenAI embeddings usage headers to int
- Add tests for null/zero Micrometer token counters and Integer factory nulls

Co-authored-by: Cursor Agent <noreply@cursor.com>
@atiaomar1978-hub

Copy link
Copy Markdown
Contributor Author

Automated review follow-up (Bugbot + Grok)

Ran Bugbot and Grok review on this changeset. Findings addressed in commit a3c47c40151:

  1. Bugbot (medium)OpenAIEmbeddingsProducer still cast OpenAI usage headers to (int), truncating large counts and inconsistent with Long header metadata. Fixed: set PROMPT_TOKENS / TOTAL_TOKENS from long values directly.

  2. Grok — Add Micrometer test ensuring null/zero token usage does not register gen_ai.client.token.usage counters. Fixed: shouldSkipMicrometerTokenCountersWhenUsageIsNullOrZero.

  3. Grok — Cover Integer factory with null arguments. Fixed: shouldConvertNullIntegerFactoryArgumentsToNullLongFields.

Grok noted optional future cleanup (single Number factory overload) — deferred to keep this PR focused.

AI-generated comment on behalf of atiaomar1978-hub

@atiaomar1978-hub
atiaomar1978-hub marked this pull request as ready for review September 4, 2026 03:00
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

🧪 CI tested the following changed modules:

  • components/camel-ai/camel-ai-observability-api
  • components/camel-ai/camel-ai-observability
  • components/camel-ai/camel-openai
  • docs

ℹ️ Dependent modules were not tested because the total number of affected modules exceeded the threshold (50). Use the test-dependents label to force testing all dependents.


🔬 Scalpel shadow comparison — Scalpel: 72 tested, 26 compile-only — current: 71 all tested

Maveniverse Scalpel detected 98 affected modules (current approach: 71).

⚠️ Modules only in Scalpel (27)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • docs
  • dummy-component

Skip-tests mode would test 72 modules (4 direct + 68 downstream), skip tests for 26 (generated code, meta-modules)

Modules Scalpel would test (72)
  • camel-a2a
  • camel-ai-observability
  • camel-ai-observability-api
  • camel-as2
  • camel-clickup
  • camel-consul
  • camel-core-all
  • camel-csv
  • camel-fhir
  • camel-groovy
  • camel-hazelcast
  • camel-hl7
  • camel-ibm-watsonx-ai
  • camel-iso8583
  • camel-java-joor-dsl
  • camel-jbang-mcp
  • camel-jbang-plugin-mcp
  • camel-jbang-plugin-route-parser
  • camel-jbang-plugin-tui
  • camel-jbang-plugin-validate
  • camel-jetty
  • camel-jsonpath
  • camel-kamelet
  • camel-kamelet-main-support
  • camel-knative-http
  • camel-langchain4j-agent
  • camel-langchain4j-chat
  • camel-langchain4j-embeddings
  • camel-langchain4j-embeddingstore
  • camel-launcher-container
  • camel-mail
  • camel-mail-microsoft-oauth
  • camel-main
  • camel-maven-plugin
  • camel-mcp-server
  • camel-micrometer-prometheus
  • camel-microprofile-health
  • camel-netty
  • camel-netty-http
  • camel-oauth
  • camel-observability-services
  • camel-once
  • camel-openai
  • camel-openapi-validator
  • camel-platform-http-main
  • camel-platform-http-vertx
  • camel-plc4x
  • camel-pubnub
  • camel-quickfix
  • camel-rest-openapi
  • camel-restdsl-openapi-plugin
  • camel-salesforce
  • camel-salesforce-codegen
  • camel-salesforce-maven-plugin
  • camel-spring-ai-chat
  • camel-spring-main
  • camel-state-store
  • camel-syslog
  • camel-telegram
  • camel-test-main-junit5
  • camel-test-main-junit6
  • camel-vertx-websocket
  • camel-webhook
  • camel-whatsapp
  • camel-xml-io-dsl
  • camel-xml-jaxb-dsl
  • camel-xml-jaxb-dsl-test-definition
  • camel-xml-jaxb-dsl-test-spring
  • camel-yaml-dsl-validator
  • camel-yaml-dsl-validator-maven-plugin
  • camel-zookeeper
  • docs
Modules with tests skipped (26)
  • apache-camel
  • camel-allcomponents
  • camel-catalog
  • camel-catalog-console
  • camel-catalog-maven
  • camel-catalog-suggest
  • camel-componentdsl
  • camel-endpointdsl
  • camel-endpointdsl-support
  • camel-itest
  • camel-jbang-core
  • camel-jbang-it
  • camel-jbang-main
  • camel-jbang-plugin-edit
  • camel-jbang-plugin-generate
  • camel-jbang-plugin-kubernetes
  • camel-jbang-plugin-test
  • camel-kamelet-main
  • camel-launcher
  • camel-report-maven-plugin
  • camel-route-parser
  • camel-yaml-dsl
  • camel-yaml-dsl-deserializers
  • camel-yaml-dsl-maven-plugin
  • coverage
  • dummy-component

ℹ️ Shadow mode — Scalpel observes but does not affect test execution. Learn more

⚠️ Some tests are disabled on GitHub Actions (@DisabledIfSystemProperty(named = "ci.env.name")) and require manual verification:

  • components/camel-ai/camel-openai: 7 test(s) disabled on GitHub Actions
Build reactor — dependencies compiled but only changed modules were tested (4 modules)
  • Camel :: AI :: Observability
  • Camel :: AI :: Observability API
  • Camel :: AI :: OpenAI
  • Camel :: Docs

⚙️ View full build and test results

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid PR. The IntegerLong widening for GenAiUsage token fields is clean and well-executed:

  • Backward compatibility preserved — the Integer convenience overload keeps LangChain4j and Spring AI callers working without changes.
  • OpenAI (int) cast truncation fixedOpenAIEmbeddingsProducer no longer narrows longint.
  • Micrometer precision is finedouble has 53 bits of mantissa, exact up to 2^53 (~9 quadrillion tokens). The .increment(tokens.doubleValue()) change is correct.
  • Test coverage is thorough — large values beyond Integer.MAX_VALUE, null/zero guards, both factory overloads, span attributes, and Micrometer counters are all covered.

Metadata note: This PR has no milestone set — should be 4.23.0 since it targets main.

This review was generated by an AI agent, Hermès, on behalf of @gnodet.

@davsclaus davsclaus added this to the 4.23.0 milestone Sep 4, 2026
@davsclaus davsclaus added the enhancement New feature or request label Sep 4, 2026
@davsclaus
davsclaus merged commit 7985fce into apache:main Sep 4, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants