Skip to content

fix(observability): NeMo Relay plugin-config teardown failure-safety + post-finalize guard (follow-up to #41551) - #41961

Closed
kshitijk4poor wants to merge 3 commits into
NousResearch:mainfrom
kshitijk4poor:fix/nemo-relay-clear-failure-and-finalize-guard
Closed

fix(observability): NeMo Relay plugin-config teardown failure-safety + post-finalize guard (follow-up to #41551)#41961
kshitijk4poor wants to merge 3 commits into
NousResearch:mainfrom
kshitijk4poor:fix/nemo-relay-clear-failure-and-finalize-guard

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

What does this PR do?

Two follow-up hardening fixes on top of the bundled NeMo Relay observability plugin lifecycle work in #41551, found while reviewing that PR. Stacks on #41551 (branched from its head).

1. clear()-failure no longer strands the runtime

_clear_plugins_toml flipped _plugin_config_initialized / _plugin_config_needs_reinit only after _resolve_awaitable(clear()) returned. close_session catches and logs a raising clear(), so on failure the flags stayed initialized=True / needs_reinit=False — and no later session would ever reinitialize plugins.toml or activate the direct fallbacks. The exporter was silently dead for the rest of the process.

Fix: flip the flags in a finally, so a partial/failed clear still re-arms reinit (or the direct fallback) on the next session start.

2. ensure_session no longer resurrects a finalized session

Any hook that funnels through ensure_session after the terminal close_session for an id re-initialized plugins.toml and pushed a scope that was never popped — silently re-arming an exporter for an ended session (and leaking the scope). on_session_end is the named example.

Fix: track a bounded set of recently-finalized session ids. A stray hook for a finalized id returns a detached, unstored _SessionState (no reinit, no scope push). An explicit on_session_start (create=True) clears the marker, so a genuine restart of the same id still works.

Note on severity: (2) has no production trigger today — the plugin on_session_end hook isn't invoked anywhere in cli.py/gateway/, and per-turn hooks fire during run_conversation, before finalize. It's defense against a future hook addition. (1) is a real latent bug that triggers whenever the relay's clear() raises.

Verification

  • _resolve_awaitable repro: drove both failure modes — clear-failure recovers (reinit fires on next start), stray post-finalize hook produces no resurrection and balanced scope.push/scope.pop.
  • Added 3 regression tests; the first two fail against the pre-fix code (verified by reverting the prod change and re-running).
  • tests/plugins/ full suite green (1089 passed), ruff clean. Behavior-preserving for all existing paths (24 prior nemo_relay tests still pass).

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • Tests (adding or improving test coverage)

Related

Follow-up to #41551 (and its parent #38232). Branched from #41551's head — merge that first, or treat these two commits as fixups to fold in.

mnajafian-nv and others added 3 commits June 7, 2026 14:46
Clear NeMo Relay plugin-config observability only after the last active Hermes session finalizes.

Use the plugin's async-safe awaitable helper for both initialize and clear so session rotation remains safe under active event loops.

Disable the direct ATIF fallback when plugins.toml already owns the ATIF exporter lifecycle to avoid duplicate trajectory export on finalization.
… succeeds

Signed-off-by: mnajafian-nv <mnajafian@nvidia.com>
…fe and guard against post-finalize resurrection

Two follow-up hardening fixes on top of the bundled NeMo Relay observability
plugin lifecycle work:

1. clear()-failure no longer strands the runtime. _clear_plugins_toml flipped
   _plugin_config_initialized/_plugin_config_needs_reinit only AFTER
   _resolve_awaitable(clear()) returned. If the relay's clear() raised
   (caught+logged in close_session), the flags stayed initialized=True /
   needs_reinit=False, so no later session ever reinitialized plugins.toml or
   activated the direct fallbacks. Flip the flags in a finally so a failed
   clear still re-arms reinit on the next session start.

2. ensure_session no longer resurrects a finalized session. Any hook that
   funnels through ensure_session after the terminal close_session for an id
   (on_session_end is the named example) re-initialized plugins.toml and
   pushed an unpopped scope, silently re-arming an exporter for an ended
   session. Track a bounded set of recently-finalized ids; a stray hook for a
   finalized id returns a detached, unstored state (no reinit, no scope push).
   An explicit on_session_start (create=True) clears the marker so a genuine
   restart of the same id still works.

Adds three regression tests; the first two fail against the pre-fix code.
Behavior-preserving for all existing paths (full plugins suite green).
@kshitijk4poor

Copy link
Copy Markdown
Collaborator Author

Closing — these two are mnajafian-nv's to address on #41551 directly (already flagged inline there). Opened this prematurely; the warnings stand as review comments on #41551, not a separate PR.

@kshitijk4poor
kshitijk4poor deleted the fix/nemo-relay-clear-failure-and-finalize-guard branch June 8, 2026 09:30
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.

2 participants