Repository navigation
feat(token-id-capture): record served response IDs - #2675
Merged
Merged
Conversation
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
5 tasks done
ananthsub
force-pushed
the
ansubramania/terminal-attribution-response-id
branch
from
August 24, 2026 03:45
10a0211 to
a9b69c7
Compare
ananthsub
marked this pull request as ready for review
August 24, 2026 04:03
ananthsub
force-pushed
the
ansubramania/terminal-attribution-response-id
branch
from
August 25, 2026 18:19
a9b69c7 to
ed44fd2
Compare
ananthsub
force-pushed
the
ansubramania/terminal-attribution-response-id
branch
from
August 25, 2026 18:27
ed44fd2 to
80154ce
Compare
4 tasks done
β¦ed call TokenEntry gains response_id so terminal attribution can match an agent's final response to the captured tokens for that model call. The capture stack is not operational yet, so the initial schema remains version 1. The Anthropic Messages mapping reuses the inner Responses envelope id instead of minting msg_<uuid>. This keeps the client-visible id aligned with the value recorded during capture. Signed-off-by: Ananth Subramaniam <ansubramania@nvidia.com>
ananthsub
force-pushed
the
ansubramania/terminal-attribution-response-id
branch
from
August 27, 2026 19:21
80154ce to
6a91461
Compare
Contributor
Author
|
/ok to test 6a91461 |
Contributor
Author
|
/claude review |
Contributor
|
SHIP β LGTM, no reliability concerns. Reviewed all 4 changed files against base. This is a small, additive change that threads the served envelope
|
ananthsub
added a commit
that referenced
this pull request
Aug 27, 2026
## What does this PR do? This PR identifies the captured model call that produced the response scored by the verifier, then anchors trajectory selection to that call. It depends on #2675. - Normalizes model-authored content across Responses, Chat Completions, and Anthropic message shapes. - Resolves the terminal model call from an explicit call ID, the served response ID, and content fingerprints. - Requires independent witnesses to agree and abstains when evidence is missing, duplicated, or contradictory. - Selects the root-to-terminal token chain, excluding auxiliary calls, sub-agent branches, and later retries. - Preserves the existing strict single-chain behavior when no terminal call can be attributed. - Records the attribution result and masking reason in rollout metrics. ## Terminal attribution flow ```mermaid flowchart TD Result["Completed /run result<br/>response scored by verifier"] --> Finalize["finalize_rollout_token_capture"] Store["Frozen TokenEntry snapshot<br/>one entry per captured model call"] --> Finalize Finalize --> Resolve["resolve_terminal"] Explicit["Explicit terminal model_call_id<br/>when supplied"] --> Agreement ResponseId["Response ID witness<br/>result.response.id = TokenEntry.response_id"] --> Agreement Content["Content witness<br/>cross-dialect fingerprint match"] --> Agreement Resolve --> Explicit Resolve --> ResponseId Resolve --> Content Agreement{"Do all available witnesses<br/>identify the same token sequence?"} Agreement -- Yes --> Terminal["Resolved terminal model_call_id"] Agreement -- No witnesses or disagreement --> Abstain["No attribution"] Terminal --> Builder["Build token-prefix forest<br/>and select root-to-terminal chain"] Builder --> Intact{"Is the terminal chain intact?"} Intact -- Yes --> Deliver["Deliver verified chain unmasked<br/>exclude auxiliary calls and sibling branches"] Intact -- No --> Mask["Mask rollout<br/>known terminal is not safely deliverable"] Abstain --> Strict["Use existing strict single-chain policy"] Strict --> Unique{"Exactly one unambiguous chain?"} Unique -- Yes --> Deliver Unique -- No --> Mask ``` The response ID does not directly determine a trajectory. It identifies a captured `TokenEntry`, whose `model_call_id` anchors selection in the token-prefix forest. Content and explicit-ID witnesses independently check that join. A disagreement fails closed instead of allowing one witness to override another. ## Known limitations - Agent observation bundles are not yet consumed as an additional terminal witness. - Token-prefix reconstruction can still split legitimate multi-call tool loops when a harness reserializes structured turns. Terminal attribution chooses the verified root; it does not restore missing token continuity. - Hermes currently sends auxiliary model-server requests through the capture prefix. The middleware treats those requests as missing generation captures and masks an otherwise complete rollout. #2678 tracks that separate completeness bug. ## Checklist - [x] I have read the [contributing guidelines](https://docs.nvidia.com/nemo/gym/latest/contribute/development-setup). - [x] The change is focused; unrelated "drive-by" edits are tracked as separate issues/PRs. - [x] Tests added or updated and pass locally, or N/A for docs-only / non-code changes (so CI unit/server checks pass when applicable). - [x] Pre-commit checks pass locally (`pre-commit run --all-files`) (so CI lint/format/copyright pass). - [x] All commits have DCO sign-off (`git commit -s`) (so the DCO check passes). --------- Signed-off-by: Kajal Jain <kajalj@nvidia.com> Signed-off-by: ananthsub <ananth.subramaniam@gmail.com> Co-authored-by: kajalj22 <kajalj@nvidia.com>
5 tasks done
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
This PR records the response envelope ID on each captured model call. The ID is a lightweight receipt that an agent can retain while token IDs and log probabilities remain in the configured token sink.
TokenEntry.response_idfield to the existing version 1 record schema.Response ID flow
sequenceDiagram participant Agent as Agent harness participant Capture as Capture middleware participant Route as Model API route participant Model as Model server participant Sink as Token sink Agent->>Capture: Request /ng-rollout/{rollout_id}/training-token-capture/v1/{dialect} Capture->>Capture: Strip prefix and set rollout_id + model_call_id Capture->>Route: Forward dialect request with capture context Route->>Model: Generate response Model-->>Route: NeMoGymResponse(id, output, token metadata) Route->>Sink: TokenEntry(model_call_id, response_id=id, token arrays, output items) alt Responses or Chat Completions Route-->>Agent: Client response carries the recorded id else Anthropic Messages Route->>Route: Convert response and preserve response.id as message.id Route-->>Agent: Message response carries the recorded id endThe response ID and token arrays are written to the same
TokenEntry. The agent only needs to retain the response ID; later code can use it to locate the corresponding captured model call.This is the first PR in the terminal-attribution stack. #2676 uses the recorded ID as one witness when resolving the model call that produced the verified response.
Checklist
pre-commit run --all-files) (so CI lint/format/copyright pass).git commit -s) (so the DCO check passes).