Skip to content

feat(nemo-agents): add support for streaming via Fabric backed agents - #973

Merged
mmogallapalli merged 11 commits into
mainfrom
mmogallapall/aircore-952-support-streaming-chat-completions-for-fabric-backed-agent
Jul 29, 2026
Merged

feat(nemo-agents): add support for streaming via Fabric backed agents#973
mmogallapalli merged 11 commits into
mainfrom
mmogallapall/aircore-952-support-streaming-chat-completions-for-fabric-backed-agent

Conversation

@mmogallapalli

@mmogallapalli mmogallapalli commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR adds streaming chat-completion support for Fabric-backed NeMo Agents as
part of AIRCORE-952.

The main flow added here is:

Fabric Runtime invoke_stream
-> raw Relay ATOF records
-> Platform best-effort assistant text extraction
-> OpenAI-compatible Chat Completions SSE
-> Studio Chat Playground streaming

This keeps Fabric/Relay as the source of streaming telemetry while Platform owns
the OpenAI-compatible serving shape expected by existing clients.

Changes

  • Updated Fabric optional dependencies to the current Fabric package set used for streaming validation.
  • Added Fabric runtime streaming wrapper around runtime.invoke_stream(...).
  • Starts served Fabric runtimes with streaming enabled.
  • Added OpenAI-compatible streaming response models and SSE framing helpers.
  • Added ATOF-to-OpenAI text chunk translation for known assistant output shapes.
  • Wired stream=true handling into the Fabric /v1/chat/completions serving path.
  • Added cleanup behavior for interrupted/disconnected streams via aclose().
  • Added mid-stream error framing.
  • Added Claude to the example agent.yaml.

Adapter Validation

Validated Studio/deployed streaming for:

  • Codex
  • Hermes
  • Claude

Design Notes

  • Platform does not invent a native streaming protocol here; it translates Fabric's Relay/ATOF streaming output into OpenAI-compatible SSE because Studio already consumes that shape.
  • The terminal Fabric stream result remains authoritative for success/failure; stream exhaustion alone is not treated as success.
  • The ATOF text extraction is intentionally conservative and only emits known assistant-visible text shapes.
  • DeepAgents is left as a follow-up once the adapter supports the Relay config required by the streaming path.

Validation

Passed:

.venv/bin/pytest plugins/nemo-agents/tests/unit/test_fabric_streaming.py -q

Result:

16 passed

Also passed:

.venv/bin/ruff check plugins/nemo-agents/src/nemo_agents_plugin/fabric/streaming.py plugins/nemo-agents/tests/unit/test_fabric_streaming.py

Working in Studio:
image

Summary by CodeRabbit

  • New Features
    • Added streaming chat completions via OpenAI-compatible SSE, including incremental content deltas, [DONE], and structured mid-stream error events.
    • Added a Claude (Anthropic) harness for agent configuration and updated the example to try Claude locally.
  • Bug Fixes
    • Improved streaming robustness: timeout/execution error normalization, correct cleanup on cancellation/early generator close, session activity refresh, and serialized concurrent streaming invocations.
  • Documentation
    • Updated local Claude setup and invocation instructions.
  • Maintenance / Tests
    • Updated optional Fabric/Hermes release-candidate version constraints and expanded unit test coverage for streaming runtime/server behavior.

Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
@github-actions github-actions Bot added the feat label Jul 29, 2026
@mmogallapalli
mmogallapalli marked this pull request as ready for review July 29, 2026 19:50
@mmogallapalli
mmogallapalli requested review from a team as code owners July 29, 2026 19:50
@mmogallapalli mmogallapalli changed the title feat(nemo-agents): add support for streaming feat(nemo-agents): add support for streaming via Fabric backed agents Jul 29, 2026
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 300e038a-389c-4629-adaa-a85a1f9561a3

📥 Commits

Reviewing files that changed from the base of the PR and between 6638717 and 03e6082.

📒 Files selected for processing (4)
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/server.py
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/streaming.py
  • plugins/nemo-agents/tests/unit/test_fabric_server.py
  • plugins/nemo-agents/tests/unit/test_fabric_streaming.py
🚧 Files skipped from review as they are similar to previous changes (4)
  • plugins/nemo-agents/tests/unit/test_fabric_streaming.py
  • plugins/nemo-agents/tests/unit/test_fabric_server.py
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/streaming.py
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/server.py

📝 Walkthrough

Walkthrough

Adds Claude harness configuration and upgrades Fabric dependencies. Implements streaming Fabric runtime and session handling, converts Fabric records to OpenAI-compatible SSE, and enables streamed /v1/chat/completions responses with cleanup and error handling.

Changes

Fabric streaming integration

Layer / File(s) Summary
Harness and adapter configuration
plugins/nemo-agents/examples/nemo-agent-config/*, plugins/nemo-agents/pyproject.toml, plugins/nemo-agents/tests/unit/test_fabric_translator.py
Adds the Claude harness, updates Fabric adapter versions, and expands harness and telemetry translation expectations.
Streaming runtime and session lifecycle
plugins/nemo-agents/src/nemo_agents_plugin/fabric/runtime.py, plugins/nemo-agents/src/nemo_agents_plugin/fabric/session_manager.py, plugins/nemo-agents/tests/unit/test_fabric_runtime.py, plugins/nemo-agents/tests/unit/test_fabric_session_manager.py
Adds streaming runtime handles, timeout and error normalization, relay-enabled runtime startup, serialized session streaming, and activity refresh.
Fabric record conversion and SSE framing
plugins/nemo-agents/src/nemo_agents_plugin/fabric/streaming.py, plugins/nemo-agents/tests/unit/test_fabric_streaming.py
Extracts assistant text from Fabric records, validates terminal results, skips duplicate summaries, and emits OpenAI-compatible SSE frames.
Streaming chat endpoint integration
plugins/nemo-agents/src/nemo_agents_plugin/fabric/server.py, plugins/nemo-agents/src/nemo_agents_plugin/fabric/serving_models.py, plugins/nemo-agents/tests/unit/test_fabric_server.py, plugins/nemo-agents/tests/unit/test_fabric_serving_models.py
Accepts streaming chat requests, returns SSE responses, maps startup failures to HTTP errors, and closes streams on errors or early cancellation.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant FabricServer
  participant FabricSessionManager
  participant FabricRuntimeStream
  Client->>FabricServer: POST /v1/chat/completions with stream=true
  FabricServer->>FabricSessionManager: Open stream_session
  FabricSessionManager->>FabricRuntimeStream: Start streaming invocation
  FabricRuntimeStream-->>FabricServer: Fabric records and terminal result
  FabricServer-->>Client: OpenAI-compatible SSE deltas and [DONE]
Loading

Possibly related PRs

Suggested reviewers: stefan-kickoff, mikeknep

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.43% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title clearly summarizes the main change: adding streaming support for Fabric-backed agents.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch mmogallapall/aircore-952-support-streaming-chat-completions-for-fabric-backed-agent

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (3)
plugins/nemo-agents/examples/nemo-agent-config/README.md (1)

37-44: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a tested Python SDK alternative in a tab set.

This Claude flow only documents CLI usage. Documentation standards require paired Python SDK and CLI examples.

🤖 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 `@plugins/nemo-agents/examples/nemo-agent-config/README.md` around lines 37 -
44, Add a tested Python SDK alternative alongside the existing Claude CLI
instructions in the README, using a tab set to present both flows. Include the
SDK authentication/setup and equivalent invocation using the existing agent
configuration, and ensure the Python example is executable and covered by the
relevant documentation tests.

Source: Coding guidelines

plugins/nemo-agents/tests/unit/test_fabric_runtime.py (1)

92-92: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use concrete annotations.

Remove the quotes around _FakeInvokeStream. As per coding guidelines, “prefer concrete type hints over string-based type hints.”

-    def invoke_stream(self, *, request: Any) -> "_FakeInvokeStream":
+    def invoke_stream(self, *, request: Any) -> _FakeInvokeStream:
...
-    def __aiter__(self) -> "_FakeInvokeStream":
+    def __aiter__(self) -> _FakeInvokeStream:

Also applies to: 115-116

🤖 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 `@plugins/nemo-agents/tests/unit/test_fabric_runtime.py` at line 92, Update the
invoke_stream method’s return annotation and the corresponding annotations at
the additionally referenced lines to use the concrete _FakeInvokeStream type
directly, removing string-based quoting while preserving the existing behavior.

Source: Coding guidelines

plugins/nemo-agents/src/nemo_agents_plugin/fabric/streaming.py (1)

15-26: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use concrete, normally imported annotation types throughout.

  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/streaming.py#L15-L26: import runtime annotation types normally instead of under TYPE_CHECKING.
  • plugins/nemo-agents/tests/unit/test_fabric_runtime.py#L92-L115: remove quotes from _FakeInvokeStream annotations.
  • plugins/nemo-agents/tests/unit/test_fabric_session_manager.py#L34-L36: remove quotes from _FakeFabricConfig.

As per coding guidelines, “prefer concrete type hints over string-based type hints” and do not import them only under TYPE_CHECKING.

🤖 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 `@plugins/nemo-agents/src/nemo_agents_plugin/fabric/streaming.py` around lines
15 - 26, Use concrete runtime annotation types: normally import
FabricRuntimeResult and FabricRuntimeStream in streaming.py instead of guarding
them with TYPE_CHECKING; remove string quotes from _FakeInvokeStream annotations
in plugins/nemo-agents/tests/unit/test_fabric_runtime.py:92-115 and from
_FakeFabricConfig in
plugins/nemo-agents/tests/unit/test_fabric_session_manager.py:34-36.

Source: Coding guidelines

🤖 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 `@plugins/nemo-agents/pyproject.toml`:
- Line 66: Update the nemo-fabric dependency in the project dependency list to
include the relay extra, preserving the existing version bounds: use
nemo-fabric[relay]>=0.1.0rc4,<0.2.0 so the fabric installation includes
streaming-path Relay dependencies.

In `@plugins/nemo-agents/src/nemo_agents_plugin/fabric/server.py`:
- Around line 244-269: The streaming response path in stream_session must
guarantee cleanup of the entered stream context even if response iteration is
cancelled or never begins. Update the response lifecycle around
_iter_streaming_chat_completion so stream_context.__aexit__ is invoked after
__aenter__ succeeds, and add a regression test at
plugins/nemo-agents/tests/unit/test_fabric_server.py:509-524 covering
cancellation or closure before the first event; no direct change is required
elsewhere.

In `@plugins/nemo-agents/src/nemo_agents_plugin/fabric/streaming.py`:
- Around line 156-165: Update the recognized-event branch and OpenAI
choice-delta handling to reject explicit roles not in _ASSISTANT_ROLES before
extracting or emitting text. Preserve current behavior when role is absent or
assistant-compatible, and apply the same guard to choice deltas.

In `@plugins/nemo-agents/tests/unit/test_fabric_server.py`:
- Around line 509-524: Extend
test_streaming_chat_completion_closes_stream_on_generator_close with a separate
case that closes or cancels the events iterator immediately after creation,
before calling __anext__ or receiving any SSE payload. Keep the already-entered
stream_context and assert fabric_stream.aclose_calls and
stream_context.exit_calls are each 1.

---

Nitpick comments:
In `@plugins/nemo-agents/examples/nemo-agent-config/README.md`:
- Around line 37-44: Add a tested Python SDK alternative alongside the existing
Claude CLI instructions in the README, using a tab set to present both flows.
Include the SDK authentication/setup and equivalent invocation using the
existing agent configuration, and ensure the Python example is executable and
covered by the relevant documentation tests.

In `@plugins/nemo-agents/src/nemo_agents_plugin/fabric/streaming.py`:
- Around line 15-26: Use concrete runtime annotation types: normally import
FabricRuntimeResult and FabricRuntimeStream in streaming.py instead of guarding
them with TYPE_CHECKING; remove string quotes from _FakeInvokeStream annotations
in plugins/nemo-agents/tests/unit/test_fabric_runtime.py:92-115 and from
_FakeFabricConfig in
plugins/nemo-agents/tests/unit/test_fabric_session_manager.py:34-36.

In `@plugins/nemo-agents/tests/unit/test_fabric_runtime.py`:
- Line 92: Update the invoke_stream method’s return annotation and the
corresponding annotations at the additionally referenced lines to use the
concrete _FakeInvokeStream type directly, removing string-based quoting while
preserving the existing behavior.
🪄 Autofix (Beta)

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: CHILL

Plan: Enterprise

Run ID: a66bdf29-5b51-43c7-9358-572080599d85

📥 Commits

Reviewing files that changed from the base of the PR and between 324d64e and abc2592.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (14)
  • plugins/nemo-agents/examples/nemo-agent-config/README.md
  • plugins/nemo-agents/examples/nemo-agent-config/agent.yaml
  • plugins/nemo-agents/pyproject.toml
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/runtime.py
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/server.py
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/serving_models.py
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/session_manager.py
  • plugins/nemo-agents/src/nemo_agents_plugin/fabric/streaming.py
  • plugins/nemo-agents/tests/unit/test_fabric_runtime.py
  • plugins/nemo-agents/tests/unit/test_fabric_server.py
  • plugins/nemo-agents/tests/unit/test_fabric_serving_models.py
  • plugins/nemo-agents/tests/unit/test_fabric_session_manager.py
  • plugins/nemo-agents/tests/unit/test_fabric_streaming.py
  • plugins/nemo-agents/tests/unit/test_fabric_translator.py

Comment thread plugins/nemo-agents/pyproject.toml
Comment thread plugins/nemo-agents/src/nemo_agents_plugin/fabric/server.py
Comment thread plugins/nemo-agents/src/nemo_agents_plugin/fabric/streaming.py
Comment thread plugins/nemo-agents/tests/unit/test_fabric_server.py
@github-actions

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 28094/35888 78.3% 62.7%
Integration Tests 16327/34606 47.2% 19.6%

Signed-off-by: Manjesh Mogallapalli <mmogallapall@nvidia.com>
@mmogallapalli
mmogallapalli force-pushed the mmogallapall/aircore-952-support-streaming-chat-completions-for-fabric-backed-agent branch from 6638717 to 03e6082 Compare July 29, 2026 20:53
@mmogallapalli
mmogallapalli requested a review from mikeknep July 29, 2026 21:05
@mmogallapalli
mmogallapalli added this pull request to the merge queue Jul 29, 2026
Merged via the queue into main with commit cd5e3dd Jul 29, 2026
58 checks passed
@mmogallapalli
mmogallapalli deleted the mmogallapall/aircore-952-support-streaming-chat-completions-for-fabric-backed-agent branch July 29, 2026 22:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants