Skip to content

feat: accept detailed token usage from adapters - #382

Open
mnajafian-nv wants to merge 6 commits into
NVIDIA:mainfrom
mnajafian-nv:feat/detailed-token-usage
Open

mnajafian-nv wants to merge 6 commits into
NVIDIA:mainfrom
mnajafian-nv:feat/detailed-token-usage

Conversation

@mnajafian-nv

@mnajafian-nv mnajafian-nv commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Add optional adapter usage fields for cache writes, reasoning tokens, peak request input, and per-model breakdowns. Core validates the fields, and the Python and TypeScript adapter contracts expose the same wire shape.

Existing payloads remain valid and the contract version stays fabric.adapter/v1alpha2. Because AgentUsage rejects unknown fields, adapters must send the new fields only to hosts with this change. RunResult.usage remains unchanged. No adapter implementation, dependency, or lockfile changes.

Details

  • Add detailed fields to AgentUsage and a closed AgentModelUsage type with per-model token and cost data.
  • Reject blank model/provider names, duplicate provider/model pairs, and negative or non-finite per-model costs.
  • Define input_tokens_include_cache to cover both cache reads and writes. Adapters normalize input_tokens when a provider includes only one category.
  • Keep RunUsage and run_usage() unchanged.
  • Regenerate the JSON Schema and TypeScript declarations, align the Python contract, and update adapter guidance and API references.

Validation

  • GitHub Rust, Python, TypeScript, adapter, wheel, and docs checks passed at 43af1b7b.
  • Focused final-head checks: core agent execution 12 passed, core schema 24 passed, Python adapter contract 121 passed, and the TypeScript adapter contract suite passed.
  • Full local suites before the final documentation-only commit: Rust 171 passed; Python 1,970 passed, 93 skipped.
  • Formatting, pre-commit, schema generation, TypeScript generation, and docs generation passed with no unexpected diff.

Where should the reviewer start?

Start with AgentUsage, AgentModelUsage, and validate_model_usage in crates/fabric-core/src/agent_execution.rs, then local_host_accepts_detailed_usage_without_changing_run_usage in runtime.rs. The key decisions are failing invalid usage at the host boundary and using one cache-inclusion flag for reads and writes.

Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)

Adapters can observe cache-write input, reasoning output, the largest
single request, and per-model usage, but AgentUsage had no fields for
them, so adapters either dropped the data or hid it in extensions.

Add cache_write_input_tokens, reasoning_tokens,
output_tokens_include_reasoning, peak_request_input_tokens, and a
closed AgentModelUsage list to AgentUsage. input_tokens_include_cache
now also covers cache-write input. Core validates per-model entries:
non-blank model and provider, each provider and model pair once
compared case-insensitively, and a finite non-negative cost_usd.

RunUsage and run_usage() are unchanged, so consumers do not see the new
fields yet. The RunUsage cache flag description now says it can cover
cache-write input that RunUsage does not report. The adapter-contract
and SDK JSON schemas are regenerated.

Signed-off-by: mnajafian-nv <mnajafian@nvidia.com>
Python adapters build AgentUsage through the Python contract, which
must accept the same fields and enforce the same rules as core so an
invalid result fails in the adapter instead of at the core boundary.

Add the new AgentUsage fields and AgentModelUsage with the same
counter bounds, non-blank identifiers, case-insensitive duplicate
check, and non-negative finite cost as core, with tests. Update the
SDK RunUsage docstring for the wider meaning of the cache flag.

Signed-off-by: mnajafian-nv <mnajafian@nvidia.com>
TypeScript adapters type their results against the generated contract
declarations, which must match the regenerated result schema.

Copy the regenerated agent-run-result schema, regenerate the
declarations with AgentModelUsage and the new AgentUsage fields, and
add type tests for the detailed fields, the boolean reasoning flag,
the required model identifier, and the closed model usage object.

Signed-off-by: mnajafian-nv <mnajafian@nvidia.com>
Adapter authors need to know when to report the new usage fields, what
the inclusion flags mean, and that NeMo Fabric does not yet pass the
fields to consumers.

Document the fields and per-model rules in the results tutorial and
the adapter-building skill, state that cache-write, reasoning, peak
request, and per-model usage are not copied into RunResult.usage,
describe the wider cache flag meaning in the Python SDK guide, and
point the adapter contribution skill at the shared fields.

Signed-off-by: mnajafian-nv <mnajafian@nvidia.com>
Regenerate the Rust and Python references with Rust 1.94.0. The new
AgentModelUsage page shifts the crate-wide sidebar positions, so most
Rust reference pages change only their position line.

Signed-off-by: mnajafian-nv <mnajafian@nvidia.com>
input_tokens_include_cache now covers both cache reads
(cached_input_tokens) and cache writes (cache_write_input_tokens), so
one flag cannot describe a provider that counts reads in input_tokens
but reports writes separately. Keep the single flag and state the rule
explicitly: true means both are included, false means both are
excluded, and an adapter whose provider mixes the two normalizes
input_tokens before reporting.

Update the Rust doc comments for AgentUsage and AgentModelUsage, the
Python contract docstring, the adapter results tutorial, and the
build-adapter skill, and regenerate the JSON Schemas, TypeScript
contract, and Rust API reference from the doc comments.

Signed-off-by: mnajafian-nv <mnajafian@nvidia.com>
@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: NVIDIA/NeMo-Fabric/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Enterprise
  • Run ID: ac627aaf-8d47-49ff-af50-3afc654db43c



📥 Commits

Reviewing files that changed from the base of the PR and between a17f316 and 43af1b7.




⛔ Files ignored due to path filters (1)
  • adapter-contract/typescript/src/generated/agent-run-result.ts is excluded by !**/generated/**



📒 Files selected for processing (104)
  • .agents/skills/contribute-adapter/SKILL.md
  • adapter-contract/python/src/nemo_fabric_adapter_contract/models.py
  • adapter-contract/typescript/schemas/agent-run-result.schema.json
  • adapter-contract/typescript/test/stable.test.ts
  • crates/fabric-core/src/agent_execution.rs
  • crates/fabric-core/src/lib.rs
  • crates/fabric-core/src/runtime.rs
  • crates/fabric-core/src/schema.rs
  • docs/adapter-contract/tutorials/results.md
  • docs/reference/api/python-library-reference/nemo_fabric.types.md
  • docs/reference/api/rust-library-reference/nemo-fabric-core/adapter-contract/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentharnessconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionsconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpserverconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmodelconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentruntimeconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentskillconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttooldefinition.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttoolsconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowentrypointconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunresultvalidationerror.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunstatus.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentmodelusage.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunerror.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunrequest.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunresult.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentusage.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterconfigfield.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterkind.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertarget.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertargettype.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-controllocation.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-descriptorsource.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-environmentownership.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-instructionmode.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpauthenticationconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpexposure.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcptransport.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-oauthtokenendpointauthmethod.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-resolutionstrategy.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-telemetryprovider.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-descriptor.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-target-descriptor.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-resolve-run-plan-from-config.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterconfigsupport.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterdescriptor.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterrequirements.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertargetdescriptor.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetryprovidersupport.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetrysupport.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-capabilityplan.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-descriptorprovenance.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-discoveryconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentplan.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-fabricconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-harnessconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionsconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpserverplan.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-metadataconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-modelconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvecontext.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadapterdescriptor.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadaptertargetdescriptor.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runplan.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimecapabilities.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimeconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-skillconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryplan.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryproviderconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-tooldefinitionconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-toolsconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowentrypointconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowtargetspec.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/enum-doctorstatus.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/fn-doctor-plan.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorcheck.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorreport.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/type-result.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/fn-version.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-runusage.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/schema/index.mdx
  • docs/sdk/python.mdx
  • schemas/adapter-contract/agent-run-result.schema.json
  • schemas/sdk/run-result.schema.json
  • sdk/python/nemo-fabric-runtime/src/nemo_fabric/types.py
  • skills/nemo-fabric-build-adapter/SKILL.md
  • tests/adapter_contract/test_agent_execution.py



Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.





Walkthrough

Agent usage contracts now include cache-write, reasoning, peak-request, and per-model metrics. Rust result validation checks model usage identifiers and costs. Runtime handling accepts detailed usage while the public RunUsage retains its existing fields.

Changes

Agent usage reporting

Layer / File(s) Summary
Define detailed usage fields and schema validation
.agents/skills/contribute-adapter/SKILL.md, adapter-contract/*, schemas/adapter-contract/*, tests/adapter_contract/*, skills/nemo-fabric-build-adapter/SKILL.md, docs/adapter-contract/tutorials/results.md
Python and JSON contracts add cache-write, reasoning, peak-request, and per-model usage fields with validation rules. Contract tests and adapter guidance cover detailed usage, field validation, and identifier uniqueness.
Validate and handle usage in Rust
crates/fabric-core/src/*, docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/*, docs/reference/api/rust-library-reference/nemo-fabric-core/{agent-config,config,doctor,error,runtime,schema}/*, docs/reference/api/rust-library-reference/nemo-fabric-core/*
Rust adds AgentModelUsage, validates model/provider identifiers, duplicate pairs, and costs, and exports the new type. Runtime tests check detailed input usage and the existing RunUsage output shape. Rust API references document the additions; API position metadata is updated.
Clarify normalized runtime usage
schemas/sdk/run-result.schema.json, sdk/python/nemo-fabric-runtime/src/nemo_fabric/types.py, docs/sdk/python.mdx, docs/reference/api/python-library-reference/nemo_fabric.types.md, docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-runusage.mdx
SDK schemas and documentation explain that RunUsage does not report cache-write input tokens and that input totals can understate total input when cache inclusion is false.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Merge Risk: ⚪ Minimal · up to 43af1

The change adds optional detailed usage fields to the adapter contract, and existing payloads remain valid. Hosts without this change will reject payloads that use the new fields, which the PR already documents. No merge-blocking risk was identified.

Pre-merge checks | Passed 4 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 41.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 36 functions across 8 files. (96 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The description includes the required Overview, reviewer starting point, Related Issues section with an allowed action keyword, ownership confirmation, and duplicate-work check. It also provides detai…
Title check Passed The title follows Conventional Commits format with the allowed lowercase type "feat", uses a concise imperative summary, is 47 characters long, and has no trailing period.

Full details: Docstring Coverage

Explanation

Docstring coverage is 41.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 36 functions across 8 files. (96 skipped: 96 unsupported.)


  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
🧪 Generate unit tests (beta)
  • Create a new PR




🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

@mnajafian-nv
mnajafian-nv marked this pull request as ready for review October 10, 2026 17:33
@mnajafian-nv
mnajafian-nv requested review from a team as code owners October 10, 2026 17:33
@mnajafian-nv

Copy link
Copy Markdown
Contributor Author

/nvskills-ci

@mnajafian-nv mnajafian-nv self-assigned this Oct 10, 2026

This branch was successfully deployed

1 active deployment
fern — 43af1b7b Deployed Oct 10, 2026 by copy-pr-bot[bot] via Preview docs #1985
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