Skip to content

fix: truncate large hook payloads before forwarding to NeMo Relay#35

Open
nanookclaw wants to merge 1 commit into
NVIDIA:mainfrom
nanookclaw:fix/hook-payload-truncation
Open

fix: truncate large hook payloads before forwarding to NeMo Relay#35
nanookclaw wants to merge 1 commit into
NVIDIA:mainfrom
nanookclaw:fix/hook-payload-truncation

Conversation

@nanookclaw

Copy link
Copy Markdown

Summary

The NeMo Relay Axum server applies a default ~2 MiB body limit on /hooks/hermes. Large but valid LLM turns silently return HTTP 413, so the interaction completes but Phoenix/ATIF telemetry is missing for that turn.

Root Cause

_forward() sends the full serialized hook payload without checking size. When a Hermes turn produces a large payload (multi-message conversations, verbose tool outputs, long reasoning chains), the Axum Json<Value> extractor rejects it before hermes::adapt(...) runs.

Change Made

File: examples/personal-community-sentiment-triage/agents/hermes/plugins/nemo-relay/__init__.py

Added a _truncate_payload() step in _forward() that progressively shrinks oversized payloads while preserving correlation metadata (task_id, session_id, model, etc.) and hook event structure:

  • Phase 1: Truncate message content strings with a proportional per-message budget
  • Phase 2: Truncate response.raw_response and assistant_message content
  • Phase 3: Truncate tool args and result strings
  • Phase 4: Aggressive — replace all content with [truncated] marker, set _truncated: true

Threshold is 1.5 MiB, safely under Axum's ~2 MiB limit. Small payloads pass through unchanged (identity return, zero overhead).

This is the client-side complement to any future server-side DefaultBodyLimit increase in NeMo Relay itself.

.../plugins/nemo-relay/__init__.py   | 146 ++++++++++++++++++++
 1 file changed, 146 insertions(+)

Testing

  • Verified small payloads pass through unchanged (identity return)
  • Verified 2 MiB message content is truncated below 1.5 MiB
  • Verified 10-message conversations get proportional truncation
  • Verified correlation metadata (task_id, session_id, model) is preserved through all phases
  • Verified response and tool call payloads are handled
  • Python syntax validation passes

Fixes #22

The NeMo Relay Axum server applies a default ~2 MiB body limit on
/hook/hermes. Large but valid LLM turns (multi-message conversations,
verbose tool outputs) silently exceed this limit, producing HTTP 413
and missing Phoenix/ATIF telemetry spans.

Add a _truncate_payload() step in _forward() that progressively
shrinks oversized payloads while preserving correlation metadata
(task_id, session_id, model, etc.) and hook event structure:

  Phase 1: truncate message content strings (proportional budget)
  Phase 2: truncate response/assistant_message content
  Phase 3: truncate tool args and result strings
  Phase 4: aggressive — replace all content with [truncated] marker

Threshold is 1.5 MiB, safely under Axum's ~2 MiB limit. Small
payloads pass through unchanged (identity return, zero overhead).

Fixes NVIDIA#22

Signed-off-by: Nanook Claw <nanook@agentmail.to>
@nanookclaw
nanookclaw force-pushed the fix/hook-payload-truncation branch from 2d5aef5 to b79b101 Compare June 8, 2026 13:33
@abhisawa-Nvidia

Copy link
Copy Markdown

@nanookclaw would you file a GH issue on NeMo Relay repo please? We can handle the case in Relay directly.

@nanookclaw

Copy link
Copy Markdown
Author

Filed NVIDIA/NeMo-Relay#255 with the Relay-side oversized hook payload handling context.

@WilliamK112

Copy link
Copy Markdown

The Relay-side follow-up requested above looks done now: NVIDIA/NeMo-Relay#261 closed NVIDIA/NeMo-Relay#255 and shipped in NeMo Relay 0.4.0.

That release raises the default hook payload limit to 20 MiB, adds NEMO_RELAY_MAX_HOOK_PAYLOAD_BYTES, and includes regression coverage for hook payloads above Axum's default limit plus structured 413 responses. This example currently pins nemo-relay-cli@0.3.0, so the smallest follow-up in this repo may be to bump the pinned CLI to 0.4.0 instead of maintaining plugin-side truncation here.

I prepared and locally validated a minimal two-file patch for that path (agents/hermes/Dockerfile version/comment update plus one stale 0.3.0 comment cleanup in nemo-relay/finalize-hook). Validation passed:

  • python scripts/check_license_headers.py --check
  • git diff --check
  • bash -n examples/personal-community-sentiment-triage/scripts/*.sh
  • python -m py_compile over the example Python files

Happy to send that minimal bump if maintainers prefer this route.

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.

Large Hermes hook payloads are rejected before Phoenix export

3 participants