-
Notifications
You must be signed in to change notification settings - Fork 35
docs: document LLM request intercept outcomes #341
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,97 @@ | ||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||
| title: "LLM Request Intercept Outcomes" | ||||||||||||||||||||||||||||||||||||
| description: "Canonical request-intercept result and managed lifecycle behavior." | ||||||||||||||||||||||||||||||||||||
| --- | ||||||||||||||||||||||||||||||||||||
| {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||||||||||||||||||||||||||||||||||||
| SPDX-License-Identifier: Apache-2.0 */} | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| Every LLM request intercept returns one canonical outcome: | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| ```json | ||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||
| "request": {"headers": {}, "content": {}}, | ||||||||||||||||||||||||||||||||||||
| "annotated_request": null, | ||||||||||||||||||||||||||||||||||||
| "pending_marks": [] | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| `request` is required. `annotated_request` defaults to `null` when omitted on | ||||||||||||||||||||||||||||||||||||
| input, and `pending_marks` defaults to an empty list. Canonical serialization | ||||||||||||||||||||||||||||||||||||
| includes all three fields. A pending mark contains only `name`, optional | ||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
| `category` and `category_profile`, and optional `data` and `metadata`. Relay | ||||||||||||||||||||||||||||||||||||
| owns event UUIDs, parent UUIDs, and timestamps. | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| ## Request Authority | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| The provider-body source of truth depends only on whether a request codec is | ||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
| active: | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| | Request codec | Provider body source | Header source | | ||||||||||||||||||||||||||||||||||||
| | --- | --- | --- | | ||||||||||||||||||||||||||||||||||||
| | No codec | `outcome.request.content` | `outcome.request.headers` | | ||||||||||||||||||||||||||||||||||||
| | Active codec | `outcome.annotated_request` | `outcome.request.headers` | | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| With an active codec, `request.content` is read-only context. Every intercept | ||||||||||||||||||||||||||||||||||||
| must return an annotation and make provider-body changes through that | ||||||||||||||||||||||||||||||||||||
| annotation, including its flattened `extra` fields for provider-specific data. | ||||||||||||||||||||||||||||||||||||
| Relay rejects a changed raw body or missing annotation at the offending | ||||||||||||||||||||||||||||||||||||
| intercept before invoking later middleware or creating an LLM lifecycle. | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does the following snippet do? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should begin with "The following example describes/does xyz..." |
||||||||||||||||||||||||||||||||||||
| ```mermaid | ||||||||||||||||||||||||||||||||||||
| flowchart TD | ||||||||||||||||||||||||||||||||||||
| INPUT["Original LlmRequest"] --> CODEC{"Request codec active?"} | ||||||||||||||||||||||||||||||||||||
| CODEC -->|No| RAWCHAIN["Run intercept chain"] | ||||||||||||||||||||||||||||||||||||
| RAWCHAIN --> RAWPROVIDER["Provider receives outcome.request"] | ||||||||||||||||||||||||||||||||||||
| CODEC -->|Yes| DECODE["Decode content into annotated_request"] | ||||||||||||||||||||||||||||||||||||
| DECODE --> INTERCEPT["Invoke next intercept"] | ||||||||||||||||||||||||||||||||||||
| INTERCEPT --> CHECKANN{"Annotation returned?"} | ||||||||||||||||||||||||||||||||||||
| CHECKANN -->|No| FAIL["Fail before lifecycle"] | ||||||||||||||||||||||||||||||||||||
| CHECKANN -->|Yes| CHECKRAW{"request.content unchanged?"} | ||||||||||||||||||||||||||||||||||||
| CHECKRAW -->|No| FAIL | ||||||||||||||||||||||||||||||||||||
| CHECKRAW -->|Yes| MORE{"More intercepts?"} | ||||||||||||||||||||||||||||||||||||
| MORE -->|Yes| INTERCEPT | ||||||||||||||||||||||||||||||||||||
| MORE -->|No| ENCODE["Encode final annotated_request"] | ||||||||||||||||||||||||||||||||||||
| ENCODE --> HEADERS["Apply final request.headers"] | ||||||||||||||||||||||||||||||||||||
| HEADERS --> PROVIDER["Provider receives one resolved LlmRequest"] | ||||||||||||||||||||||||||||||||||||
| ``` | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| Python callbacks return `LLMRequestInterceptOutcome`; Rust callbacks return | ||||||||||||||||||||||||||||||||||||
| `LlmRequestInterceptOutcome`; Go callbacks return | ||||||||||||||||||||||||||||||||||||
| `LLMRequestInterceptOutcome`; and Node.js and WebAssembly callbacks return | ||||||||||||||||||||||||||||||||||||
| `{ request, annotated?, pendingMarks? }`, with `categoryProfile` on each | ||||||||||||||||||||||||||||||||||||
| JavaScript pending-mark DTO. The canonical JSON forms retain `pending_marks` | ||||||||||||||||||||||||||||||||||||
| and `category_profile`. Public C callbacks write one owned canonical outcome | ||||||||||||||||||||||||||||||||||||
| JSON string. Native ABI v1 uses one host-owned outcome JSON string. Rust and | ||||||||||||||||||||||||||||||||||||
| Python `grpc-v1` worker SDKs return their canonical outcome type in a | ||||||||||||||||||||||||||||||||||||
| `JsonEnvelope` whose schema is | ||||||||||||||||||||||||||||||||||||
| `nemo.relay.LlmRequestInterceptOutcome@1`. | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+60
to
+69
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| The standalone request-intercept helper returns the complete outcome but does | ||||||||||||||||||||||||||||||||||||
| not emit its pending marks because it does not own an LLM lifecycle. | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| ## Managed Lifecycle | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| Managed execution runs all effective global and scope-local intercepts before | ||||||||||||||||||||||||||||||||||||
| creating the LLM handle. Each accepted request/annotation pair feeds the next | ||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||
| intercept under the authority rules above, while pending marks append in | ||||||||||||||||||||||||||||||||||||
| middleware order. A breaking | ||||||||||||||||||||||||||||||||||||
| intercept's marks are retained. If any intercept fails or its boundary result | ||||||||||||||||||||||||||||||||||||
| is malformed, Relay discards all accumulated marks and creates no LLM | ||||||||||||||||||||||||||||||||||||
| lifecycle. | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| After successful interception, Relay creates the handle and captures one | ||||||||||||||||||||||||||||||||||||
| subscriber snapshot. It emits the LLM start at `T`, every pending mark at | ||||||||||||||||||||||||||||||||||||
| `T + 1µs` in returned order with the LLM UUID as parent, and the LLM end no | ||||||||||||||||||||||||||||||||||||
| earlier than `T + 1µs`. Streaming and non-streaming calls use the same rules. | ||||||||||||||||||||||||||||||||||||
| Pending marks are never added to the provider request, annotated request, | ||||||||||||||||||||||||||||||||||||
| codec input, sanitizer input, or start payload. | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| ## Migration | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| This finalizes unpublished native ABI v1 and `grpc-v1` contracts. Rebuild all | ||||||||||||||||||||||||||||||||||||
| development native plugins and workers. Replace tuple results, split C/Go | ||||||||||||||||||||||||||||||||||||
| outputs, metadata envelopes, and parallel mark-aware registrations with the | ||||||||||||||||||||||||||||||||||||
| canonical outcome and the existing `register_llm_request_intercept` | ||||||||||||||||||||||||||||||||||||
| registration name. | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you provide a description about what this does? Is this the LLM request intercept or the outcome?