Skip to content

feat: add native OpenAI streaming - #201

Draft
AjayThorve wants to merge 1 commit into
NVIDIA:mainfrom
AjayThorve:feat/native-openai-streaming
Draft

feat: add native OpenAI streaming#201
AjayThorve wants to merge 1 commit into
NVIDIA:mainfrom
AjayThorve:feat/native-openai-streaming

Conversation

@AjayThorve

@AjayThorve AjayThorve commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Overview

Adds the consolidated adapter-native OpenAI Chat Completions streaming contract defined by FABRIC-162. This introduces Runtime.invoke_openai_stream without changing or coupling it to the existing NeMo Relay-backed Runtime.invoke_stream API.

This is intentionally the one larger PR in the three-PR sequence because it defines a public Rust/Python/adapter wire contract and carries its generated JSON Schema and API-reference output. It adds no dependencies or lockfile changes.

Breaking changes: none.

Details

  • Adds the Rust core and PyO3 invocation path gated by both the cached runtime capability and the authoritative resolved adapter descriptor claim.
  • Keeps the additive optional lifecycle operation on fabric.adapter/v1alpha2; the authenticated side channel negotiates its independent fabric.openai_stream/v1alpha1 transport version.
  • Defines a single-use authenticated loopback HTTP transport carrying correlated chunked NDJSON records while keeping the terminal lifecycle response on stdout.
  • Adds the Python OpenAIInvokeStream async iterator with separate immutable terminal results, empty-stream support, early-consumer-close draining, exact-once invocation, and one-active-turn enforcement.
  • Validates the frozen openai.chat_completions.chunk/v1 profile, record identity, sequence monotonicity, explicit end records, record limits, and exact JSON numeric bounds through u64::MAX.
  • Serializes concurrent adapter writes, closes partial connections on ordinary failure and cancellation, and preserves the primary adapter error or cancellation over secondary finalization failures.
  • Adds schemas, generated API references, SDK/adapter documentation, common-host guidance, consumer skills, and native conformance coverage.

Validation

  • cargo fmt --all --check — passed.
  • just test-rust — passed across the Rust workspace, including 75 core tests.
  • just test-python — 771 passed, 16 skipped.
  • Focused lifecycle and SDK streaming suite — 59 passed.
  • just build-python rebuilt the native extension; tests/python/test_native_sdk.py::test_native_sdk then passed the real subprocess/loopback streaming path.
  • just docs — 0 errors; the unauthenticated Fern redirects check emitted its expected warning.
  • Generated-schema snapshot checks, docs tests, repository-wide pre-commit hooks, and git diff --check passed.
  • No live model-backed adapter invocation was run.

Where should the reviewer start?

Start with crates/fabric-core/src/runtime.rs for capability gating and the transport contract, then adapters/common/src/nemo_fabric_adapters/common/lifecycle.py for failure precedence, and python/src/nemo_fabric/openai_streaming.py for consumer-side stream semantics. The end-to-end contract tests are in tests/python/test_openai_streaming.py and tests/adapters/test_adapters_common_lifecycle.py.

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

  • Relates to FABRIC-162

  • I confirm this contribution is my own work, or I have the right to submit it under this project's license.

  • I searched existing issues and open pull requests, and this does not duplicate existing work.

Summary by CodeRabbit

  • New Features

    • Added native OpenAI Chat Completions streaming to the Python and Rust SDKs.
    • Streams now support validated chunks, terminal results, cleanup, backpressure, authentication, and error handling.
    • Added capability detection through supports_openai_streaming.
    • Kept native OpenAI streaming separate from NeMo Relay streaming.
  • Documentation

    • Added SDK, adapter, schema, and API reference documentation for native OpenAI streaming.
    • Clarified adapter requirements, lifecycle behavior, and usage examples.
  • Tests

    • Added comprehensive coverage for streaming, validation, security, cancellation, failures, and cleanup.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The PR adds native OpenAI Chat Completions streaming through authenticated loopback NDJSON transport. It updates the Rust core, adapter lifecycle, Python SDK, schemas, tests, API references, and integration guidance while keeping Relay streaming separate.

Changes

Native OpenAI streaming

Layer / File(s) Summary
Core protocol and runtime dispatch
crates/fabric-core/..., crates/fabric-python/...
Adds streaming contracts, schemas, transport validation, lifecycle dispatch, redaction, capability errors, public exports, and Python bindings.
Adapter lifecycle transport and validation
adapters/common/...
Adds invoke_openai_stream, authenticated chunked NDJSON emission, chunk validation, sequencing, finalization, and failure handling.
Python stream listener and runtime API
python/src/nemo_fabric/...
Adds OpenAIInvokeStream, bounded async iteration, result(), aclose(), protocol validation, cleanup, and runtime integration.
Adapter contract and JSON schemas
schemas/..., docs/adapter-contract/...
Defines invocation and record schemas and documents capability, transport, chunk, terminal-result, cleanup, and Relay-separation rules.
Protocol validation and integration tests
tests/..., crates/fabric-core/src/runtime.rs
Adds lifecycle, SDK, transport, authentication, sequencing, cleanup, capability, failure, redaction, fixture, and smoke-test coverage.
SDK documentation and generated references
docs/..., skills/..., scripts/..., README.md
Separates OpenAI and Relay streaming documentation and adds public API references and integration guidance.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Runtime
  participant OpenAIInvokeStream
  participant NativeBinding
  participant AdapterLifecycle
  participant AdapterRuntime
  Runtime->>OpenAIInvokeStream: create native stream
  OpenAIInvokeStream->>NativeBinding: invoke_openai_stream with transport
  NativeBinding->>AdapterLifecycle: send lifecycle request
  AdapterLifecycle->>AdapterRuntime: invoke_openai_stream(payload, emit)
  AdapterRuntime->>AdapterLifecycle: emit correlated chunks
  AdapterLifecycle-->>OpenAIInvokeStream: deliver NDJSON chunks and end record
  OpenAIInvokeStream-->>Runtime: return terminal RunResult
Loading

Possibly related PRs

  • NVIDIA/NeMo-Fabric#109: Adds a separate Python SDK streaming path related to the distinction between Relay streaming and native OpenAI streaming.
  • NVIDIA/NeMo-Fabric#199: Adds adapter-contract and schema infrastructure used by the native streaming contract.
  • NVIDIA/NeMo-Fabric#202: Adds related adapter support for emitting ChatResponseChunk values under the native streaming contract.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.41% which is insufficient. The required threshold is 80.00%. 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.
Title check ✅ Passed The title follows Conventional Commits format and clearly summarizes the native OpenAI streaming change.
Description check ✅ Passed The description includes the required overview, reviewer starting points, related issue, validation details, and contribution confirmations.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@github-actions

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 10

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@adapters/common/src/nemo_fabric_adapters/common/lifecycle.py`:
- Around line 604-611: Update the lifecycle cleanup block around writer.finish()
so adapter_error always takes precedence over a finalization failure, including
asyncio.CancelledError. When both errors exist, attach the finish exception as
context to adapter_error and re-raise adapter_error; only raise the finish
exception when no adapter error exists, and remove the stderr-only handling.
- Around line 298-370: The OpenAI chunk schema is missing the explicit uint64
maximum bound. Update the Rust schema source for the chunk’s created field to
enforce both 0 and u64::MAX, regenerate the schema snapshot, and add or update
shared tests covering values at u64::MAX and just beyond it.

In `@crates/fabric-core/src/schema.rs`:
- Around line 341-374: The test
openai_stream_schemas_freeze_transport_and_record_invariants must assert the
generated OpenAiStreamSink token schema’s pattern in addition to minLength. Add
an assertion on sink["properties"]["token"]["pattern"] requiring the exact
header-safe pattern ^[^\r\n]*\S[^\r\n]*$, while preserving the existing
invariants.

In `@docs/reference/api/python-library-reference/nemo_fabric.openai_streaming.md`:
- Line 22: Update the OpenAIInvokeStream source docstring in the relevant class
or method under python/src/nemo_fabric/openai_streaming.py to wrap result and
aclose in Markdown backticks instead of reStructuredText roles, then regenerate
the API reference using just docs; do not edit the generated Markdown directly.

In
`@docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaichatcompletionchunk.mdx`:
- Line 2: Update the Rust API-reference title-generation logic to render the
identifier segment OpenAi as OpenAI, then regenerate the affected references.
Ensure the generated titles are corrected in
docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaichatcompletionchunk.mdx:2,
struct-openaichatcompletionchunkchoice.mdx:2,
struct-openaichatcompletionchunkdelta.mdx:2, and
struct-openaistreaminvocation.mdx:2, producing “OpenAI” with the existing
spacing and title structure.

In
`@docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx`:
- Around line 4-14: Update the OpenAiStreamSink documentation comment in
runtime.rs to say “generated by NVIDIA NeMo Fabric,” replacing the current
abbreviated product wording. Then run just docs and regenerate the schema
snapshots so the generated API pages and openai-stream-invocation.schema.json
reflect the updated description.

In `@python/src/nemo_fabric/runtime.py`:
- Line 76: Define a shared stream protocol near the runtime type declarations
with _finalized: bool, _task: asyncio.Task[Any], and an aclose() method, then
annotate _current_stream with that protocol instead of the InvokeStream |
OpenAIInvokeStream union. Ensure both stream implementations satisfy the
protocol so Runtime’s existing accesses remain type-checked.

In `@skills/nemo-fabric-integrate/references/sdk-api-inventory.md`:
- Around line 68-71: Update the stream-finalization guidance to document await
stream.result() as a valid way to finalize OpenAIInvokeStream before starting
another turn, including that it drains unread chunks. Preserve the requirement
to fully consume or await aclose() for other streams, and explicitly state that
Relay InvokeStream.result() does not consume unread ATOF records.

In `@tests/adapters/test_adapters_common_lifecycle.py`:
- Around line 282-334: Extend the parameter list in
test_common_host_rejects_chunks_outside_the_declared_openai_profile with invalid
chunks covering a wrong object discriminator, non-list choices, non-mapping
delta, and malformed tool_calls, logprobs, and usage. Keep each case consistent
with the existing minimal chunk structure and verify they all raise
LifecycleError with code lifecycle_invalid_openai_stream_event through
_validated_openai_chunk.

In `@tests/python/test_openai_streaming.py`:
- Line 19: Rename the conflicting parameter named openai_streaming in
_runtime_wrapper and
test_native_and_relay_streaming_capabilities_are_independent to
native_streaming, updating all references and preserving the existing behavior
while keeping the module alias unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 2b2ee309-c94e-4ac7-9b61-f86b57be0f1a

📥 Commits

Reviewing files that changed from the base of the PR and between 4112bea and 4c4539c.

📒 Files selected for processing (74)
  • README.md
  • adapters/common/README.md
  • adapters/common/src/nemo_fabric_adapters/common/lifecycle.py
  • crates/fabric-core/src/error.rs
  • crates/fabric-core/src/lib.rs
  • crates/fabric-core/src/runtime.rs
  • crates/fabric-core/src/schema.rs
  • crates/fabric-python/src/lib.rs
  • docs/adapter-contract/conformance.md
  • docs/adapter-contract/execution.md
  • docs/index.yml
  • docs/reference/api/python-library-reference/index.md
  • docs/reference/api/python-library-reference/nemo_fabric.openai_streaming.md
  • docs/reference/api/python-library-reference/nemo_fabric.runtime.md
  • docs/reference/api/python-library-reference/nemo_fabric.streaming.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-execution/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/index.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/fn-version.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/constant-openai-chat-completions-chunk-profile.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/constant-openai-stream-host.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/constant-openai-stream-protocol-version.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-errorstage.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaichatcompletionchunkobject.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamhost.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamprofile.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamprotocolversion.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-runstatus.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/fn-invoke-openai-stream.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/fn-invoke-runtime.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/fn-prepare-environment.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/fn-run-plan.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/fn-start-runtime.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/fn-stop-runtime.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaichatcompletionchunk.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaichatcompletionchunkchoice.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaichatcompletionchunkdelta.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreaminvocation.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamtransport.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-runrequest.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-runresult.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-runtimecontext.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-runtimehandle.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-runtimetelemetrycontext.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-telemetryref.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/schema/enum-schemaname.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/schema/index.mdx
  • docs/sdk/python.mdx
  • python/src/nemo_fabric/__init__.py
  • python/src/nemo_fabric/_native.pyi
  • python/src/nemo_fabric/openai_streaming.py
  • python/src/nemo_fabric/runtime.py
  • schemas/SCHEMA.md
  • schemas/adapter-contract/legacy/openai-stream-invocation.schema.json
  • schemas/adapter-contract/legacy/openai-stream-record.schema.json
  • scripts/docs/enhance_python_api_reference.py
  • scripts/generate_api_docs.sh
  • skills/nemo-fabric-build-adapter/SKILL.md
  • skills/nemo-fabric-integrate/SKILL.md
  • skills/nemo-fabric-integrate/references/sdk-api-inventory.md
  • tests/adapters/test_adapters_common_lifecycle.py
  • tests/docs/test_python_api_docs.py
  • tests/fixtures/hermes-shim-agent/adapters/hermes-shim/fabric-adapter.json
  • tests/fixtures/hermes-shim-agent/adapters/hermes-shim/src/nemo_fabric_test_adapters/hermes_shim/adapter.py
  • tests/python/test_native_sdk.py
  • tests/python/test_openai_streaming.py

Comment thread adapters/common/src/nemo_fabric_adapters/common/lifecycle.py
Comment thread adapters/common/src/nemo_fabric_adapters/common/lifecycle.py
Comment thread crates/fabric-core/src/schema.rs
Comment thread docs/reference/api/python-library-reference/nemo_fabric.openai_streaming.md Outdated
self._status = RuntimeStatus.ACTIVE
self._current_task: asyncio.Task[Any] | None = None
self._current_stream: InvokeStream | None = None
self._current_stream: InvokeStream | OpenAIInvokeStream | None = None

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make the shared stream contract explicit.

Runtime now reaches into _finalized and _task on both InvokeStream and OpenAIInvokeStream at lines 151, 275, 317, 366, and 433. These are private attributes of two unrelated classes. No base class or protocol enforces that both keep them. A rename in either class breaks the other call sites, and a type checker cannot catch it because the union permits attribute access on both members.

Define a small Protocol with _finalized: bool, _task: asyncio.Task[Any], and aclose(), and annotate _current_stream with it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/src/nemo_fabric/runtime.py` at line 76, Define a shared stream
protocol near the runtime type declarations with _finalized: bool, _task:
asyncio.Task[Any], and an aclose() method, then annotate _current_stream with
that protocol instead of the InvokeStream | OpenAIInvokeStream union. Ensure
both stream implementations satisfy the protocol so Runtime’s existing accesses
remain type-checked.

Comment thread skills/nemo-fabric-integrate/references/sdk-api-inventory.md
Comment thread tests/adapters/test_adapters_common_lifecycle.py
Comment thread tests/python/test_openai_streaming.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/fabric-core/src/runtime.rs`:
- Around line 1332-1363: Extract the two inline streaming redaction statements
in the LocalHostInvocation::OpenAiStream branch into a named
redact_openai_stream_invocation helper placed beside redact_adapter_invocation.
Have the helper redact the runtime context environment and replace stream.token
with the redacted value, then call it for persisted streaming invocations while
preserving the existing lifecycle payload behavior.

In
`@docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx`:
- Around line 24-68: Update the Rust reference generator in the variant-field
rendering logic of scripts/docs/generate_rust_library_reference.py so fields
under each enum variant’s `#### Fields` label use `#####` headings instead of
`###`, preserving proper nesting and unique variant-scoped anchors. Regenerate
the documentation with `just docs` and verify the generated Chunk and End
sections reflect the corrected hierarchy.

In `@python/src/nemo_fabric/runtime.py`:
- Around line 116-121: Update Runtime.supports_openai_streaming to require both
_plan.capabilities.streaming and the resolved adapter descriptor’s streaming
capability, matching the core contract and the existing guard. In
tests/python/test_openai_streaming.py lines 40-52, add
adapter_descriptor.descriptor.capabilities to _plan, parameterize it
independently from the plan capability, and verify a plan-only capability raises
FabricCapabilityError with code openai_streaming_unavailable before any native
call.

In `@scripts/docs/generate_rust_library_reference.py`:
- Line 512: Add an inline comment next to the title normalization in the
relevant generation flow documenting that the regex targets “Open Ai” only when
followed by an uppercase letter, inserts a single trailing space, and leaves
terminal “Open Ai” unchanged.

In `@tests/adapters/test_adapters_common_lifecycle.py`:
- Around line 132-136: Update the three listener.records.get() awaits in the
lifecycle test to use asyncio.wait_for with the file’s established timeout
pattern, ensuring each read fails promptly if no record is emitted while
preserving the existing record collection behavior.

In `@tests/python/test_openai_streaming.py`:
- Around line 40-52: Update the plan fixture’s adapter_descriptor.descriptor to
include an explicit capabilities block with streaming enabled, while retaining
the existing top-level capabilities.streaming parameter. Add or adjust coverage
so a plan advertising streaming is also tested against a descriptor without
streaming, verifying the descriptor capability rule is enforced.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: a470239a-0912-451e-8132-5b34a5667402

📥 Commits

Reviewing files that changed from the base of the PR and between 4c4539c and 0368c79.

📒 Files selected for processing (24)
  • adapters/common/src/nemo_fabric_adapters/common/lifecycle.py
  • crates/fabric-core/src/runtime.rs
  • crates/fabric-core/src/schema.rs
  • docs/reference/api/python-library-reference/nemo_fabric.openai_streaming.md
  • docs/reference/api/python-library-reference/nemo_fabric.runtime.md
  • docs/reference/api/python-library-reference/nemo_fabric.streaming.md
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaichatcompletionchunkobject.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamhost.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamprofile.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamprotocolversion.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaichatcompletionchunk.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaichatcompletionchunkchoice.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaichatcompletionchunkdelta.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreaminvocation.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamtransport.mdx
  • python/src/nemo_fabric/openai_streaming.py
  • python/src/nemo_fabric/runtime.py
  • python/src/nemo_fabric/streaming.py
  • schemas/adapter-contract/legacy/openai-stream-record.schema.json
  • scripts/docs/generate_rust_library_reference.py
  • tests/adapters/test_adapters_common_lifecycle.py
  • tests/python/test_openai_streaming.py

Comment thread crates/fabric-core/src/runtime.rs
Comment thread python/src/nemo_fabric/runtime.py
Comment thread scripts/docs/generate_rust_library_reference.py
Comment thread tests/adapters/test_adapters_common_lifecycle.py
Comment thread tests/python/test_openai_streaming.py
Signed-off-by: Ajay Thorve <athorve@nvidia.com>
@AjayThorve
AjayThorve force-pushed the feat/native-openai-streaming branch from 0368c79 to 8c3c5a3 Compare August 11, 2026 16:17

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/fabric-core/src/runtime.rs`:
- Around line 1230-1243: Update run_local_host_openai_stream_adapter to avoid
the fixed local_host_invoke_timeout deadline for active streams: use a
streaming-specific timeout and ensure each received stream chunk resets or
extends the terminal-response deadline in exchange_lifecycle_message. Preserve
the existing timeout behavior for non-streaming invocations while allowing
healthy streams to continue as chunks arrive.

In `@python/src/nemo_fabric/runtime.py`:
- Around line 330-334: Extract the repeated active-stream validation into a
private _ensure_no_active_stream method on the containing class, preserving the
existing _current_stream/_finalized condition and FabricStateError message.
Replace the guards in invoke, invoke_stream, and the current method with calls
to this helper.

In `@tests/python/test_openai_streaming.py`:
- Around line 497-502: Update the local wait_for_end function to use a small
non-zero asyncio.sleep delay while polling stream._end_observed, replacing the
zero-delay yield; keep the existing wait_for_end polling behavior and one-second
asyncio.wait_for timeout unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: f407ed28-62a8-4da2-a9ad-a88098095427

📥 Commits

Reviewing files that changed from the base of the PR and between 0368c79 and 8c3c5a3.

📒 Files selected for processing (12)
  • crates/fabric-core/src/runtime.rs
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatifstorageconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatofsinkconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • python/src/nemo_fabric/runtime.py
  • schemas/adapter-contract/legacy/openai-stream-invocation.schema.json
  • scripts/docs/generate_rust_library_reference.py
  • tests/adapters/test_adapters_common_lifecycle.py
  • tests/python/test_openai_streaming.py
📜 Review details
⏰ Context from checks skipped due to timeout. (17)
  • GitHub Check: Test (Python 3.13, linux-amd64)
  • GitHub Check: Test (Python 3.11, linux-amd64)
  • GitHub Check: Test (Python 3.13, windows-amd64)
  • GitHub Check: Test (Python 3.11, macos-arm64)
  • GitHub Check: Test (Python 3.11, linux-arm64)
  • GitHub Check: Test (Python 3.14, macos-arm64)
  • GitHub Check: Test (Python 3.13, macos-arm64)
  • GitHub Check: Test (Python 3.11, windows-amd64)
  • GitHub Check: Test (Python 3.12, windows-amd64)
  • GitHub Check: Test (Python 3.12, macos-arm64)
  • GitHub Check: Test (Python 3.12, linux-amd64)
  • GitHub Check: Test (Python 3.14, linux-arm64)
  • GitHub Check: Test (Python 3.13, linux-arm64)
  • GitHub Check: Test (Python 3.12, linux-arm64)
  • GitHub Check: Test (Python 3.14, windows-amd64)
  • GitHub Check: Pre-commit
  • GitHub Check: Test (arm64)
🧰 Additional context used
📓 Path-based instructions (36)
**/*.{rs,py,pyi,json,yaml,yml}

📄 CodeRabbit inference engine (.agents/skills/contribute-api/SKILL.md)

Determine and update every affected public surface, including the CLI, PyO3 bindings, Python SDK, type stubs, schemas, and adapter contract, so they remain in parity.

Files:

  • scripts/docs/generate_rust_library_reference.py
  • schemas/adapter-contract/legacy/openai-stream-invocation.schema.json
  • tests/adapters/test_adapters_common_lifecycle.py
  • python/src/nemo_fabric/runtime.py
  • tests/python/test_openai_streaming.py
  • crates/fabric-core/src/runtime.rs
**/*

📄 CodeRabbit inference engine (.agents/skills/karpathy-guidelines/SKILL.md)

**/*: Before implementing, explicitly state assumptions, surface ambiguity and tradeoffs, present multiple interpretations when relevant, and ask for clarification rather than silently deciding or proceeding when requirements are unclear.
Prefer the minimum code needed to solve the requested problem: avoid speculative features, unnecessary abstractions, unrequested flexibility, and handling of impossible scenarios; simplify overcomplicated solutions.
When editing existing code, make surgical changes only: do not modify unrelated code, comments, formatting, or pre-existing dead code; match the existing style, and remove only unused imports, variables, or functions introduced by your changes.
Define verifiable success criteria for each task, such as writing regression tests for bugs and invalid-input tests for validation, then verify the implementation against those criteria. For multi-step work, state a brief plan with a verification check for each step.

**/*: Always spell NVIDIA in all caps; do not use Nvidia, nvidia, nVidia, nVIDIA, or NV.
Use an NVIDIA before a noun, because the name begins with an “en” sound.
Do not add a registered trademark symbol after NVIDIA when referring to the company; use trademark symbols with product names only when required by the document type or legal guidance.
Verify official capitalization, spacing, hyphenation, and spelling for NVIDIA and third-party product names; do not rewrite official product names for grammar or title-case rules.
Precede NVIDIA product names with NVIDIA on first mention when natural and accurate, and link the first mention when the destination helps the reader.
On first use, include the company name and full model qualifier when it helps identify the model; preserve official capitalization and punctuation, and use shorter family names only after establishing the full name.
For learning-oriented and developer content, do not force trademark symbols unless explicitly required; for press, ...

Files:

  • scripts/docs/generate_rust_library_reference.py
  • schemas/adapter-contract/legacy/openai-stream-invocation.schema.json
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatifstorageconfig.mdx
  • tests/adapters/test_adapters_common_lifecycle.py
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • python/src/nemo_fabric/runtime.py
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatofsinkconfig.mdx
  • tests/python/test_openai_streaming.py
  • crates/fabric-core/src/runtime.rs
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx
**/*.{rs,py}

📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)

For native binding changes, run cargo check -p fabric-python --locked.

Use snake_case for functions and variables; use PascalCase for Rust types and Python classes.

Files:

  • scripts/docs/generate_rust_library_reference.py
  • tests/adapters/test_adapters_common_lifecycle.py
  • python/src/nemo_fabric/runtime.py
  • tests/python/test_openai_streaming.py
  • crates/fabric-core/src/runtime.rs
**/*.{py,pyi}

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

If Python code or a Python-facing adapter changes, run just test-python.

In Python SDK, adapters, examples, and tests, follow the existing style, use type annotations for public APIs, and keep native binding declarations synchronized with their Rust implementations.

Files:

  • scripts/docs/generate_rust_library_reference.py
  • tests/adapters/test_adapters_common_lifecycle.py
  • python/src/nemo_fabric/runtime.py
  • tests/python/test_openai_streaming.py
**/*.{rs,py,pyi}

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

**/*.{rs,py,pyi}: If public configuration types change, confirm schema snapshot tests in just test-rust pass and review generated schema diffs.
For schema or public contract changes, run both language suites and review changes under schemas/ and generated API references.

Files:

  • scripts/docs/generate_rust_library_reference.py
  • tests/adapters/test_adapters_common_lifecycle.py
  • python/src/nemo_fabric/runtime.py
  • tests/python/test_openai_streaming.py
  • crates/fabric-core/src/runtime.rs
**/*.{py,pyi,rs}

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

For Python SDK or PyO3 binding changes, use python-tests, run focused pytest tests first, then just test-python; rebuild with just build-python when native code or packaging changes.

Public contract changes must keep native Python binding declarations synchronized with their Rust implementations.

Files:

  • scripts/docs/generate_rust_library_reference.py
  • tests/adapters/test_adapters_common_lifecycle.py
  • python/src/nemo_fabric/runtime.py
  • tests/python/test_openai_streaming.py
  • crates/fabric-core/src/runtime.rs
**/*.{rs,py,toml}

📄 CodeRabbit inference engine (.agents/skills/update-project-version/SKILL.md)

When editing version helpers, verify every nemo-fabric-* workspace package through Cargo metadata and reject a static version in python/pyproject.toml.

Files:

  • scripts/docs/generate_rust_library_reference.py
  • tests/adapters/test_adapters_common_lifecycle.py
  • python/src/nemo_fabric/runtime.py
  • tests/python/test_openai_streaming.py
  • crates/fabric-core/src/runtime.rs
**/*.{toml,rs,py}

📄 CodeRabbit inference engine (.agents/skills/update-project-version/SKILL.md)

Avoid blind repository-wide replacement of version-like strings; distinguish package-version references from examples and unrelated dependency versions.

Files:

  • scripts/docs/generate_rust_library_reference.py
  • tests/adapters/test_adapters_common_lifecycle.py
  • python/src/nemo_fabric/runtime.py
  • tests/python/test_openai_streaming.py
  • crates/fabric-core/src/runtime.rs
scripts/docs/generate_rust_library_reference.py

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/SKILL.md)

For Rust API reference changes, update scripts/docs/generate_rust_library_reference.py when the generator itself must change.

Files:

  • scripts/docs/generate_rust_library_reference.py
**/*.{md,mdx,yml,py,rs,sh}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/SKILL.md)

Keep documentation aligned with current NeMo Fabric behavior, repository layout, entry points, commands, package names, APIs, bindings, and support claims.

Files:

  • scripts/docs/generate_rust_library_reference.py
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatifstorageconfig.mdx
  • tests/adapters/test_adapters_common_lifecycle.py
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • python/src/nemo_fabric/runtime.py
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatofsinkconfig.mdx
  • tests/python/test_openai_streaming.py
  • crates/fabric-core/src/runtime.rs
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx
**/*.{json,jsonschema}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Public contract changes must keep checked-in JSON Schema snapshots synchronized.

Files:

  • schemas/adapter-contract/legacy/openai-stream-invocation.schema.json
schemas/**/*

⚙️ CodeRabbit configuration file

schemas/**/*: Schemas are generated public contract snapshots. Check that schema diffs correspond to intentional Rust type changes and are covered by core tests.

Files:

  • schemas/adapter-contract/legacy/openai-stream-invocation.schema.json
{README.md,docs/**/*.{md,mdx,yml},examples/**/*.{md,mdx,yml}}

📄 CodeRabbit inference engine (.agents/skills/contribute-docs/SKILL.md)

Keep package names, repository references, and build commands current in documentation and examples.

Files:

  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatifstorageconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatofsinkconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx
{docs/**/*.{md,mdx,yml},examples/**/*.{md,mdx,yml}}

📄 CodeRabbit inference engine (.agents/skills/contribute-docs/SKILL.md)

Update relevant getting-started, reference, adapter, and example documentation when the corresponding examples or adapters change.

Files:

  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatifstorageconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatofsinkconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx
**/*.mdx

📄 CodeRabbit inference engine (.agents/skills/contribute-docs/SKILL.md)

In MDX files, use JSX comment delimiters ({/* and */}) for top-of-file comments, including SPDX headers; do not use HTML comments.

**/*.mdx: For documentation site changes, run just docs to regenerate Python and Rust API references and validate Fern configuration.
MDX files must use the specified JSX-comment SPDX header.

Files:

  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatifstorageconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatofsinkconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx
docs/**/*.{md,mdx,yml}

📄 CodeRabbit inference engine (.agents/skills/contribute-docs/SKILL.md)

Run just docs when the documentation site changes.

Files:

  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatifstorageconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatofsinkconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx
**/*.{md,mdx,rst}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/assets/nvidia-style-guide.md)

**/*.{md,mdx,rst}: For NeMo Fabric documentation, verify technical claims against the current repository, public API, or documented command before reviewing style.
Always spell NVIDIA in all caps; do not use Nvidia, nvidia, or NV.
Format commands, code elements, expressions, package names, file names, and paths as inline code.
Use descriptive link text; avoid raw URLs and weak anchors such as here or read more.
Use title case consistently for technical documentation headings.
Introduce code blocks, lists, tables, and images with complete sentences.
Write procedures as imperative, parallel steps; split long procedures into smaller tasks.
Prefer active voice, present tense, short sentences, contractions, and plain English while preserving necessary technical precision.
Use can for possibility and reserve may for permission.
Use after for temporal relationships instead of once, and prefer refer to over see when directing readers to another resource.
Avoid culture-specific idioms, unnecessary Latinisms, jokes, and marketing exaggeration in technical documentation.
Spell out months in body text, avoid ordinal dates, and use clear time zones.
Spell out whole numbers from zero through nine unless they are technical values, parameters, versions, or UI values; use numerals for 10 or greater and commas in thousands.
Do not add trademark symbols to learning-oriented documentation unless the source, platform, or legal guidance explicitly requires them.
Do not replace precise technical terms with simpler words when doing so would lose precision.
Do not flag passive voice when the actor is unknown or the action is the important part.
Do not rewrite API names, package names, command flags, or code literals for style.

**/*.{md,mdx,rst}: Use consistent title case for technical-document headings and table headers; avoid quotation marks, ampersands, and exclamation marks in headings, while preserving official product, event, research, and whitepaper title ...

Files:

  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatifstorageconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatofsinkconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx
docs/reference/api/**/*

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/SKILL.md)

Treat all files under docs/reference/api/ as generated output and do not modify them directly.

Files:

  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatifstorageconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatofsinkconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx
docs/**/*.mdx

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/SKILL.md)

docs/**/*.mdx: Use source-relative links with the target .mdx extension for links between files under docs/; do not use Fern site-root paths.
Use {/* ... */} delimiters for top-of-file MDX SPDX comments, not HTML comment delimiters.

Files:

  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatifstorageconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatofsinkconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx
**/*.{md,mdx}

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/SKILL.md)

**/*.{md,mdx}: Use the full product name NVIDIA NeMo Fabric on first use, typically in the title and H1; use NeMo Fabric thereafter. Use fabric alone only for the CLI tool and surround it with backticks.
Treat incorrect or stale commands, package names, paths, APIs, support claims, procedures, examples, terminology, or public behavior documentation as blocking issues.
Capitalize NVIDIA correctly and format code, commands, paths, and filenames as inline code where needed.
Use title case for technical-documentation headings.
Introduce code blocks, tables, and lists with complete lead-in sentences; ensure examples match current APIs and build commands.
Use descriptive anchor text, avoid raw URLs and generic labels such as here, and use repository-relative .mdx paths for links within docs/.
Prefer active voice, present tense, short sentences, plain English, consistent terminology, and imperative, parallel, scannable procedures.
Use after instead of once when expressing temporal sequence, and use can rather than may when describing possibility rather than permission.
Avoid ambiguous numeric dates and ordinal dates in body text.
For learning-oriented documentation, do not force trademark symbols unless the source document explicitly requires them.
When reporting documentation-review findings, lead with Must fix, Should fix, and Nice to have categories; include file path, line reference, current problem, rationale, and a concrete rewrite or direction.

Files:

  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatifstorageconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatofsinkconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx
docs/**

📄 CodeRabbit inference engine (AGENTS.md)

Run just docs after changing the documentation site.

Files:

  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatifstorageconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatofsinkconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx
{docs/**,README.md,AGENTS.md}

⚙️ CodeRabbit configuration file

{docs/**,README.md,AGENTS.md}: Review documentation for technical accuracy against the current API, command correctness, and consistency with generated schemas.
For links between files under docs/, require paths relative to the source file with the target file's .mdx extension so they work in both Fern builds and repository browsers. Flag Fern site-root links such as NeMo Fabric overview; use the repository-relative equivalent, such as NeMo Fabric overview.

Files:

  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatifstorageconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatofsinkconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx
{*.md,**/*.md,**/*.mdx,**/*.ipynb}

⚙️ CodeRabbit configuration file

{*.md,**/*.md,**/*.mdx,**/*.ipynb}: Enforce the product name in user-facing prose: use "NVIDIA NeMo Fabric" on first use and "NeMo Fabric" thereafter. Flag standalone capitalized "Fabric" when it refers to the product. Do not flag the lowercase fabric CLI command, package/import/crate names, code identifiers, API symbols, configuration keys, file paths, or unrelated generic uses of the word.

Files:

  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatifstorageconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatofsinkconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx
tests/adapters/**/*.py

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

tests/adapters/**/*.py: If an adapter or integration changes, run its focused tests.
For adapter behavior changes, run focused adapter tests under tests/adapters, then run just test-python.

Files:

  • tests/adapters/test_adapters_common_lifecycle.py
tests/**/*.{rs,py}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

When adding functionality, include tests in the corresponding Rust crate or the relevant area under tests/.

Files:

  • tests/adapters/test_adapters_common_lifecycle.py
  • tests/python/test_openai_streaming.py
tests/**/*.py

📄 CodeRabbit inference engine (.agents/skills/python-tests/SKILL.md)

tests/**/*.py: Use pytest to run Python tests.
Do not add @pytest.mark.asyncio to tests; async tests are automatically detected by the async runner.
Do not add -> None return type annotations to test functions.
When mocking a class, use unittest.mock.MagicMock or AsyncMock, using the spec argument when necessary, rather than defining a new class.
Prefix mocked class names with mock, not fake.
Prefer pytest fixtures over helper methods.
If a fixture is needed in multiple test files, define it once in conftest.py rather than repeating it.
Define fixtures using @pytest.fixture(name="<fixture_name>"[, scope="<scope>"]) and a <fixture_name>_fixture function; specify scope only when it is not function.
Prefer pytest.mark.parametrize over separate tests for different input types.
Use @pytest.mark.usefixtures when a fixture is needed but its returned value is unused or it returns no value.
Avoid defensive programming in tests; access expected values directly so missing data raises a clear failure, such as using results["data"] instead of results.get("data").
When adapter installation metadata changes, packaging metadata tests must directly assert that the root project depends unconditionally on the exact-version nemo-fabric-runtime distribution.
Packaging metadata tests must verify that each root harness extra delegates to the matching version of the leaf adapter's harness extra.
Packaging metadata tests must verify that bare leaf dependencies remain adapter-owned and that the root adapter-tests dependency group installs each leaf through its harness extra.
Packaging metadata tests must verify that every leaf provides full; only adapters importing NeMo Relay Python APIs provide relay, while adapters using an external Relay executable have full equal to harness.

Files:

  • tests/adapters/test_adapters_common_lifecycle.py
  • tests/python/test_openai_streaming.py
{tests/**,python/tests/**}

⚙️ CodeRabbit configuration file

{tests/**,python/tests/**}: Tests should cover the behavior promised by the changed API surface, including error paths, lifecycle cleanup, and SDK/native parity where relevant.

Files:

  • tests/adapters/test_adapters_common_lifecycle.py
  • tests/python/test_openai_streaming.py
python/src/nemo_fabric/**/*.py

📄 CodeRabbit inference engine (.agents/skills/review-doc-style/SKILL.md)

For Python API reference changes, update source docstrings under python/src/nemo_fabric/ instead of generated API reference files.

Files:

  • python/src/nemo_fabric/runtime.py
python/src/nemo_fabric/**/*.{py,rs}

📄 CodeRabbit inference engine (.agents/skills/maintain-packaging/SKILL.md)

Ensure native extension naming and placement remain compatible with downstream consumers, including the editable maturin build producing nemo_fabric._native.

Files:

  • python/src/nemo_fabric/runtime.py
python/src/nemo_fabric/**/*

⚙️ CodeRabbit configuration file

python/src/nemo_fabric/**/*: Review Python SDK changes for typed API consistency, import-time dependency neutrality, async/session behavior, and parity with the native extension.
Stubs and runtime implementations should stay aligned.

Files:

  • python/src/nemo_fabric/runtime.py
**/*.rs

📄 CodeRabbit inference engine (.agents/skills/contribute-api/SKILL.md)

Implement new runtime or binding behavior in the shared Rust core first.

Files:

  • crates/fabric-core/src/runtime.rs
**/*.{rs,toml}

📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)

For any Rust change, run just test-rust and cargo fmt --all -- --check.

For Rust core, CLI, or shared runtime semantic changes, run Rust formatting and tests, and add Python tests when behavior is exposed through the SDK.

Use Rust stable tooling; format Rust code with cargo fmt --all, verify formatting with cargo fmt --all -- --check, and compile with cargo check --workspace --locked.

Files:

  • crates/fabric-core/src/runtime.rs
crates/fabric-core/**/*.{rs,py}

📄 CodeRabbit inference engine (.agents/skills/prepare-pr/SKILL.md)

Changes under crates/fabric-core must run both the Rust and Python test suites.

Files:

  • crates/fabric-core/src/runtime.rs
**/*.{rs,rmeta}

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

If Rust code changes, run cargo fmt --all -- --check and just test-rust.

Files:

  • crates/fabric-core/src/runtime.rs
crates/fabric-core/**/*.rs

📄 CodeRabbit inference engine (.agents/skills/validate-change/SKILL.md)

If crates/fabric-core changes in a way exposed through Python, run both the Rust and Python suites.

For Rust API reference changes, update Rust documentation comments under crates/fabric-core/ instead of generated API reference files.

Files:

  • crates/fabric-core/src/runtime.rs
crates/fabric-core/src/**/*.rs

⚙️ CodeRabbit configuration file

crates/fabric-core/src/**/*.rs: Review the Rust core for runtime lifecycle correctness, handle validation, capability routing accuracy, schema stability, and error semantics.
Public API changes should match committed schemas, tests, and documentation.

Files:

  • crates/fabric-core/src/runtime.rs
🧠 Learnings (3)
📚 Learning: 2026-08-07T07:15:33.918Z
Learnt from: AnuradhaKaruppiah
Repo: NVIDIA/NeMo-Fabric PR: 186
File: schemas/adapter-contract/legacy/adapter-invocation.schema.json:176-176
Timestamp: 2026-08-07T07:15:33.918Z
Learning: For the NeMo Fabric v1alpha southbound adapter contract, treat the adapter descriptor's `contract_version` as the version of the complete contract, including `RuntimeContext`. Keep `RuntimeContext` strict by rejecting unknown properties, and require a negotiated contract-version change for additive shape changes.

Applied to files:

  • schemas/adapter-contract/legacy/openai-stream-invocation.schema.json
📚 Learning: 2026-07-24T16:07:22.255Z
Learnt from: AjayThorve
Repo: NVIDIA/NeMo-Fabric PR: 118
File: docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterdescriptor.mdx:5-5
Timestamp: 2026-07-24T16:07:22.255Z
Learning: In this repo, files generated under `docs/reference/api/**` are NVIDIA NeMo Fabric API reference output. When reviewing changes to these generated pages, do not treat sidebar `position`/ordering updates as direct manual edits—these can be regenerated by running `just docs` after adding public types. Only flag substantive content changes that are not explained by generation.

Applied to files:

  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatifstorageconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatofsinkconfig.mdx
  • docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx
📚 Learning: 2026-06-28T04:03:32.877Z
Learnt from: AjayThorve
Repo: NVIDIA/NeMo-Fabric PR: 26
File: python/tests/smoke_typed_config.py:163-177
Timestamp: 2026-06-28T04:03:32.877Z
Learning: In NVIDIA NeMo Fabric Python SDK serialization of `RuntimeCapabilities` (to satisfy the “parity contract” with Rust core and the CLI), do not emit metadata keys when the corresponding metadata is absent. Instead, omit those fields entirely so the produced JSON matches the Rust/CLI output (e.g., avoid `null`, empty objects, or placeholder metadata). During review, verify the serializer/builders follow this omission rule and that Python outputs/parity tests reflect the same shape.

Applied to files:

  • python/src/nemo_fabric/runtime.py
🪛 ast-grep (0.45.1)
python/src/nemo_fabric/runtime.py

[info] 194-194: use jsonify instead of json.dumps for JSON output
Context: json.dumps(self._runtime.to_mapping())
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 195-195: use jsonify instead of json.dumps for JSON output
Context: json.dumps(payload)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 207-207: use jsonify instead of json.dumps for JSON output
Context: json.dumps(dict(openai_stream_transport))
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)

tests/python/test_openai_streaming.py

[info] 206-206: use jsonify instead of json.dumps for JSON output
Context: json.dumps(record, separators=(",", ":"))
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 224-224: use jsonify instead of json.dumps for JSON output
Context: json.dumps(record, separators=(",", ":"))
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 253-253: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_result(request, runtime, invocation_id=invocation_id))
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 263-269: use jsonify instead of json.dumps for JSON output
Context: json.dumps(
_result(
request,
runtime,
invocation_id=f"invocation-{len(mock_native.requests)}",
)
)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 327-329: use jsonify instead of json.dumps for JSON output
Context: json.dumps(
_result(request, runtime, invocation_id="invocation-empty")
)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 365-367: use jsonify instead of json.dumps for JSON output
Context: json.dumps(
_result(request, runtime, invocation_id="invocation-many")
)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 385-387: use jsonify instead of json.dumps for JSON output
Context: json.dumps(
_result(request, runtime, invocation_id="invocation-without-stream")
)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 417-419: use jsonify instead of json.dumps for JSON output
Context: json.dumps(
_result(request, runtime, invocation_id="invocation-after-probe")
)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 453-455: use jsonify instead of json.dumps for JSON output
Context: json.dumps(
_result(request, runtime, invocation_id="invocation-late-stream")
)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 483-489: use jsonify instead of json.dumps for JSON output
Context: json.dumps(
_result(
request,
runtime,
invocation_id="invocation-cancel-after-end",
)
)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 556-563: use jsonify instead of json.dumps for JSON output
Context: json.dumps(
_result(
request,
runtime,
invocation_id="invocation-failed",
failed=True,
)
)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 586-588: use jsonify instead of json.dumps for JSON output
Context: json.dumps(
_result(request, runtime, invocation_id="invocation-terminal")
)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 675-675: use jsonify instead of json.dumps for JSON output
Context: json.dumps(record)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 689-689: use jsonify instead of json.dumps for JSON output
Context: json.dumps(nonfinite)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 703-703: use jsonify instead of json.dumps for JSON output
Context: json.dumps(_record())
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 706-712: use jsonify instead of json.dumps for JSON output
Context: json.dumps(
_record(
sequence=1,
invocation_id="invocation-other",
chunk=_chunk("chunk-2", "other"),
)
)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)


[info] 796-798: use jsonify instead of json.dumps for JSON output
Context: json.dumps(
_record(record_type="end"), separators=(",", ":")
)
Note: [CWE-116] Improper Encoding or Escaping of Output.

(use-jsonify)

🪛 LanguageTool
docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx

[grammar] ~26-~26: Ensure spelling is correct
Context: ...reaminvocation.mdx): One adapter-native OpenAI streaming invocation. - [OpenAiStreamSink](struct-openaistrea...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~41-~41: Ensure spelling is correct
Context: ...num-openaistreamprofile.mdx): Supported OpenAI-compatible chunk profile. - [OpenAiStreamProtocolVersion](enum-openai...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~50-~50: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...for adapter-native OpenAI streaming. - [OPENAI_STREAM_PROTOCOL_VERSION](constant-opena...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[grammar] ~50-~50: Ensure spelling is correct
Context: ...und protocol version for adapter-native OpenAI streaming. ## Functions - [invoke_openai_stream](fn-i...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🪛 Ruff (0.16.1)
tests/adapters/test_adapters_common_lifecycle.py

[warning] 94-94: Missing return type annotation for private function start

Add return type annotation: None

(ANN202)


[warning] 97-97: Missing return type annotation for private function invoke

Add return type annotation: Never

(ANN202)


[warning] 98-98: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 100-100: Missing return type annotation for private function invoke_openai_stream

(ANN202)


[warning] 122-122: Missing return type annotation for private function stop

Add return type annotation: None

(ANN202)


[warning] 251-251: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 255-255: Missing return type annotation for private function open_connection

(ANN202)


[warning] 255-255: Missing type annotation for *_args

(ANN002)


[warning] 255-255: Missing type annotation for **_kwargs

(ANN003)


[warning] 290-290: Missing return type annotation for private function connect

(ANN202)


[warning] 299-299: Missing return type annotation for private function invoke_openai_stream

Add return type annotation: Never

(ANN202)


[warning] 341-341: Missing return type annotation for private function start

Add return type annotation: None

(ANN202)


[warning] 344-344: Missing return type annotation for private function invoke

(ANN202)


[warning] 347-347: Missing return type annotation for private function stop

Add return type annotation: None

(ANN202)


[warning] 432-432: Missing return type annotation for private function start

Add return type annotation: None

(ANN202)


[warning] 435-435: Missing return type annotation for private function invoke

Add return type annotation: None

(ANN202)


[warning] 438-438: Missing return type annotation for private function stop

Add return type annotation: None

(ANN202)

python/src/nemo_fabric/runtime.py

[error] 307-307: Function argument input is shadowing a Python builtin

(A002)


[warning] 307-307: Dynamically typed expressions (typing.Any) are disallowed in input

(ANN401)


[warning] 324-329: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 331-334: Avoid specifying long messages outside the exception class

(TRY003)

tests/python/test_openai_streaming.py

[warning] 19-19: Use from nemo_fabric import openai_streaming in lieu of alias

Replace with from nemo_fabric import openai_streaming

(PLR0402)


[warning] 125-125: Dynamically typed expressions (typing.Any) are disallowed in sequence

(ANN401)


[warning] 143-143: Dynamically typed expressions (typing.Any) are disallowed in stream

(ANN401)


[warning] 185-185: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 318-318: Missing return type annotation for private function invoke_empty

(ANN202)


[warning] 356-356: Missing return type annotation for private function invoke_many

(ANN202)


[warning] 383-383: Missing return type annotation for private function invoke_without_stream

(ANN202)


[warning] 406-406: Missing return type annotation for private function invoke_after_probe

(ANN202)


[error] 410-410: Possible hardcoded password assigned to argument: "token"

(S106)


[warning] 436-436: Missing return type annotation for private function invoke_before_stream

(ANN202)


[warning] 473-473: Missing return type annotation for private function invoke_after_end

(ANN202)


[warning] 498-499: Use asyncio.Event instead of awaiting asyncio.sleep in a while loop

(ASYNC110)


[warning] 547-547: Missing return type annotation for private function invoke_failed

(ANN202)


[warning] 577-577: Missing return type annotation for private function invoke_mismatch

(ANN202)


[warning] 718-718: Missing return type annotation for private function invoke_without_end

Add return type annotation: Never

(ANN202)


[warning] 731-731: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 743-743: Missing return type annotation for private function invoke_invalid_chunk

Add return type annotation: Never

(ANN202)


[warning] 759-759: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 781-781: Missing return type annotation for private function candidate

(ANN202)


[warning] 846-846: Boolean-typed positional argument in function definition

(FBT001)


[warning] 847-847: Boolean-typed positional argument in function definition

(FBT001)


[warning] 887-887: Missing return type annotation for private function fail_create_task

Add return type annotation: Never

(ANN202)


[warning] 889-889: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 891-891: Missing return type annotation for private function invoke

Add return type annotation: Never

(ANN202)


[warning] 892-892: Avoid specifying long messages outside the exception class

(TRY003)


[warning] 920-920: Missing return type annotation for private function invoke_with_bad_token

Add return type annotation: Never

(ANN202)


[error] 929-929: Possible hardcoded password assigned to argument: "token"

(S106)


[warning] 931-931: Avoid specifying long messages outside the exception class

(TRY003)

🔇 Additional comments (35)
tests/adapters/test_adapters_common_lifecycle.py (5)

365-410: Validation branches in _validated_openai_chunk remain uncovered.

The parametrized list covers missing model, boolean index, blank id, blank model, created overflow, and index overflow. _validated_openai_chunk also rejects a wrong object discriminator, a non-list choices, a non-mapping delta, and malformed tool_calls, logprobs, and usage. Those branches have no case here. This repeats an earlier review note.


15-15: LGTM!

Also applies to: 30-78


80-157: LGTM!

Also applies to: 160-190, 193-228


231-268: LGTM!

Also applies to: 270-312, 314-363


418-450: LGTM!

crates/fabric-core/src/runtime.rs (5)

40-46: LGTM!

Also applies to: 349-560, 564-587, 618-627, 675-681


823-869: LGTM!


1245-1297: LGTM!

Also applies to: 1332-1362


2130-2160: LGTM!


2912-3009: LGTM!

Also applies to: 3076-3145, 3237-3394

python/src/nemo_fabric/runtime.py (4)

25-25: LGTM!

Also applies to: 76-76


176-178: LGTM!

Also applies to: 194-216, 250-251


304-329: LGTM!

Also applies to: 335-352, 382-383


116-133: 🩺 Stability & Availability

Keep the current adapter_descriptor lookup. RunPlan inherits Mapping.get and preserves adapter_descriptor as an extension field. The typed adapter field does not include nested capabilities.

			> Likely an incorrect or invalid review comment.
tests/python/test_openai_streaming.py (7)

1-62: LGTM!

Also applies to: 65-140


143-229: LGTM!

Also applies to: 231-295


298-403: LGTM!

Also applies to: 405-469


472-496: LGTM!

Also applies to: 503-543, 546-598


601-714: LGTM!

Also applies to: 717-769


772-837: LGTM!

Also applies to: 840-881


884-941: LGTM!

schemas/adapter-contract/legacy/openai-stream-invocation.schema.json (2)

150-239: LGTM!

Also applies to: 344-368


1-149: LGTM!

Also applies to: 240-343

scripts/docs/generate_rust_library_reference.py (2)

399-401: LGTM!


514-514: LGTM!

docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatifstorageconfig.mdx (1)

26-42: LGTM!

Also applies to: 54-86

docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-relayatofsinkconfig.mdx (1)

26-38: LGTM!

Also applies to: 50-78

docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx (2)

12-12: LGTM!

Also applies to: 296-327


26-294: LGTM!

Also applies to: 336-514

docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/enum-openaistreamrecord.mdx (2)

24-68: The heading hierarchy is now correct: ### Chunk#### Fields##### sequence: u64. The generator change at scripts/docs/generate_rust_library_reference.py lines 399-401 resolves the previously reported heading skip.


1-23: LGTM!

Also applies to: 70-143

docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx (2)

5-5: LGTM!

Also applies to: 23-44


46-54: 🎯 Functional Correctness

The four linked pages exist and are committed. No documentation change is required.

			> Likely an incorrect or invalid review comment.
docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-openaistreamsink.mdx (2)

1-14: The full product name "NVIDIA NeMo Fabric" now appears in the description, and it flows from the Rust doc comment at crates/fabric-core/src/runtime.rs line 395 into both this page and schemas/adapter-contract/legacy/openai-stream-invocation.schema.json. The earlier finding is resolved.


16-48: LGTM!

Also applies to: 50-123

Comment on lines +1230 to +1243
fn run_local_host_openai_stream_adapter(
plan: &RunPlan,
runtime: &RuntimeHandle,
request: RunRequest,
transport: OpenAiStreamTransport,
) -> Result<RunResult> {
run_local_host_invocation_with_timeout(
plan,
runtime,
request,
LocalHostInvocation::OpenAiStream(transport),
local_host_invoke_timeout(plan)?,
)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Inspect the invoke timeout constant, the lifecycle exchange, and any streaming-specific timeout handling.
set -euo pipefail

rg -n 'LOCAL_HOST_INVOKE_TIMEOUT|LOCAL_HOST_START_TIMEOUT|LOCAL_HOST_STOP_TIMEOUT' crates/fabric-core/src/runtime.rs

ast-grep run --pattern 'fn exchange_lifecycle_message($$$) { $$$ }' --lang rust crates/fabric-core/src/runtime.rs

# Check whether documentation states a streaming-specific timeout expectation.
rg -n -i 'timeout' docs/adapter-contract/execution.md

Repository: NVIDIA/NeMo-Fabric

Length of output: 511


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- runtime structure ---'
ast-grep outline crates/fabric-core/src/runtime.rs

printf '%s\n' '--- timeout and lifecycle call sites ---'
rg -n -C 8 'exchange_lifecycle_message|local_host_invoke_timeout|invalidate_timed_out_local_host|OpenAiStream|host_timeout' crates/fabric-core/src/runtime.rs

printf '%s\n' '--- execution contract streaming requirements ---'
rg -n -C 5 -i 'stream|timeout|chunk|end record|terminal' docs/adapter-contract/execution.md

Repository: NVIDIA/NeMo-Fabric

Length of output: 46170


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- timeout resolution and invocation exchange ---'
sed -n '1240,1410p' crates/fabric-core/src/runtime.rs
sed -n '1789,1875p' crates/fabric-core/src/runtime.rs
sed -n '1510,1545p' crates/fabric-core/src/runtime.rs

printf '%s\n' '--- stream transport implementation and host behavior ---'
rg -n -C 8 'invoke_openai_stream|100 Continue|chunked|OpenAiStreamRecord|recv_timeout|emit' --glob '*.rs' --glob '*.py' --glob '*.pyi' .

printf '%s\n' '--- timeout configuration contract and tests ---'
rg -n -C 6 'timeout_seconds|runtime.timeout|LOCAL_HOST_INVOKE_TIMEOUT|invoke_timeout' crates schemas docs python

Repository: NVIDIA/NeMo-Fabric

Length of output: 50375


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

path = Path("crates/fabric-core/src/runtime.rs")
text = path.read_text()

stream_call = re.search(
    r"fn run_local_host_openai_stream_adapter\b.*?"
    r"local_host_invoke_timeout\(plan\)\?\s*,",
    text,
    re.S,
)
exchange = re.search(
    r"fn exchange_lifecycle_message\b.*?"
    r"host\.responses\.recv_timeout\(timeout\)",
    text,
    re.S,
)
progress_reset = re.search(
    r"recv_timeout\(timeout\).*?(?:reset|deadline|timeout)",
    text,
    re.S | re.I,
)

print(f"stream_uses_shared_timeout={bool(stream_call)}")
print(f"exchange_waits_for_terminal_response={bool(exchange)}")
print(f"deadline_reset_or_progress_timeout_logic={bool(progress_reset)}")
PY

Repository: NVIDIA/NeMo-Fabric

Length of output: 276


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- shared timeout resolution ---'
sed -n '1245,1265p' crates/fabric-core/src/runtime.rs

printf '%s\n' '--- streaming invocation lifecycle ---'
sed -n '1290,1400p' crates/fabric-core/src/runtime.rs

printf '%s\n' '--- terminal response wait ---'
sed -n '1789,1865p' crates/fabric-core/src/runtime.rs

printf '%s\n' '--- exact timeout-related runtime tests ---'
sed -n '3470,3525p' crates/fabric-core/src/runtime.rs
sed -n '3660,3750p' crates/fabric-core/src/runtime.rs

printf '%s\n' '--- focused stream implementation files ---'
fd -t f -e py -e rs | while read -r file; do
  rg -l -m 1 'class _OpenAIStreamListener|def invoke_openai_stream|async def invoke_openai_stream' "$file" 2>/dev/null || true
done

Repository: NVIDIA/NeMo-Fabric

Length of output: 13615


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path

p = Path("crates/fabric-core/src/runtime.rs")
lines = p.read_text().splitlines()

for start, end in ((1245, 1265), (1290, 1400), (1789, 1865)):
    print(f"--- runtime.rs:{start}-{end} ---")
    for number in range(start, end + 1):
        print(f"{number}: {lines[number - 1]}")
PY

Repository: NVIDIA/NeMo-Fabric

Length of output: 9065


Use a streaming-specific timeout or reset the deadline on stream progress.

Native streaming shares local_host_invoke_timeout(plan), which defaults to LOCAL_HOST_INVOKE_TIMEOUT (one hour). exchange_lifecycle_message waits for one terminal stdout response with a fixed recv_timeout; stream chunks do not extend this wait. A longer stream therefore returns host_timeout and terminates the host, even while chunks are arriving.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/fabric-core/src/runtime.rs` around lines 1230 - 1243, Update
run_local_host_openai_stream_adapter to avoid the fixed
local_host_invoke_timeout deadline for active streams: use a streaming-specific
timeout and ensure each received stream chunk resets or extends the
terminal-response deadline in exchange_lifecycle_message. Preserve the existing
timeout behavior for non-streaming invocations while allowing healthy streams to
continue as chunks arrive.

Comment on lines +330 to +334
if self._current_stream is not None and not self._current_stream._finalized:
raise FabricStateError(
"a streaming invocation is active; fully consume it or call "
"`await stream.aclose()` before starting another turn"
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Extract the duplicated active-stream guard.

The same five-line guard now appears three times: lines 164-168 in invoke, lines 288-292 in invoke_stream, and lines 330-334 here. All three read the private _finalized attribute and raise the same FabricStateError with the same message.

Extract one private helper and call it from all three sites.

♻️ Proposed helper
def _ensure_no_active_stream(self) -> None:
    if self._current_stream is not None and not self._current_stream._finalized:
        raise FabricStateError(
            "a streaming invocation is active; fully consume it or call "
            "`await stream.aclose()` before starting another turn"
        )
-        if self._current_stream is not None and not self._current_stream._finalized:
-            raise FabricStateError(
-                "a streaming invocation is active; fully consume it or call "
-                "`await stream.aclose()` before starting another turn"
-            )
+        self._ensure_no_active_stream()
         self._ensure_invocable()
🧰 Tools
🪛 Ruff (0.16.1)

[warning] 331-334: Avoid specifying long messages outside the exception class

(TRY003)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/src/nemo_fabric/runtime.py` around lines 330 - 334, Extract the
repeated active-stream validation into a private _ensure_no_active_stream method
on the containing class, preserving the existing _current_stream/_finalized
condition and FabricStateError message. Replace the guards in invoke,
invoke_stream, and the current method with calls to this helper.

Comment on lines +497 to +502
async def wait_for_end() -> None:
while not stream._end_observed:
await asyncio.sleep(0)

try:
await asyncio.wait_for(wait_for_end(), timeout=1)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win

Replace the zero-delay busy wait with a real sleep.

wait_for_end polls stream._end_observed with await asyncio.sleep(0). The producing work runs in a worker thread, so this loop spins the event loop at full speed for up to the one-second budget. It monopolizes CPU and can delay the loop callbacks that set _end_observed, which makes the test slower and flakier on loaded CI.

Use a small non-zero sleep.

💚 Proposed fix
     async def wait_for_end() -> None:
         while not stream._end_observed:
-            await asyncio.sleep(0)
+            await asyncio.sleep(0.005)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async def wait_for_end() -> None:
while not stream._end_observed:
await asyncio.sleep(0)
try:
await asyncio.wait_for(wait_for_end(), timeout=1)
async def wait_for_end() -> None:
while not stream._end_observed:
await asyncio.sleep(0.005)
try:
await asyncio.wait_for(wait_for_end(), timeout=1)
🧰 Tools
🪛 Ruff (0.16.1)

[warning] 498-499: Use asyncio.Event instead of awaiting asyncio.sleep in a while loop

(ASYNC110)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/python/test_openai_streaming.py` around lines 497 - 502, Update the
local wait_for_end function to use a small non-zero asyncio.sleep delay while
polling stream._end_observed, replacing the zero-delay yield; keep the existing
wait_for_end polling behavior and one-second asyncio.wait_for timeout unchanged.

Source: Linters/SAST tools

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