Reject mixed Nemotron Parse endpoint lists - #2543
Conversation
Greptile SummaryThe PR rejects mixed NVIDIA Build and self-hosted Nemotron Parse endpoint lists across parameter construction and direct execution paths, with aligned tests and documentation.
|
| Filename | Overview |
|---|---|
| nemo_retriever/src/nemo_retriever/common/params/models.py | Adds early mixed-endpoint validation, but raw URL precedence lets a whitespace primary alias bypass validation of the fallback list. |
| nemo_retriever/src/nemo_retriever/common/params/utils.py | Adds the shared endpoint classifier and rejection logic; the public helper's docstring is incomplete. |
| nemo_retriever/src/nemo_retriever/operators/extract/parse/nemotron_parse.py | Adds defense-in-depth checks before contract selection, remote invocation, and NIMClient allocation. |
| nemo_retriever/tests/test_actor_operators.py | Covers mixed-list rejection for explicit and implicit models, direct pages, and actor construction. |
| nemo_retriever/tests/test_params_models.py | Covers ordinary mixed-list rejection at ExtractParams construction but omits whitespace alias precedence. |
| docs/docs/extraction/prerequisites-support-matrix.md | Correctly documents the homogeneous endpoint-list requirement and remediation. |
| docs/docs/extraction/troubleshoot.md | Adds consistent troubleshooting guidance for rejected mixed endpoint lists. |
Prompt To Fix All With AI
### Issue 1
nemo_retriever/src/nemo_retriever/common/params/models.py:586
**Whitespace alias bypasses validation**
When `nemotron_parse_invoke_url` contains only whitespace and `invoke_url` contains mixed endpoints, raw truthiness validates the empty primary value instead of the effective fallback list, so `ExtractParams` construction succeeds instead of raising the required validation error.
```suggestion
validate_nemotron_parse_endpoint_list(
self.nemotron_parse_invoke_url
if str(self.nemotron_parse_invoke_url or "").strip()
else self.invoke_url
)
```
### Issue 2
nemo_retriever/src/nemo_retriever/common/params/utils.py:16-17
**Validator contract lacks documentation**
The new public helper does not document its parameter, normalized tuple return value, or mixed-endpoint `ValueError`, leaving callers without the required public interface contract.
```suggestion
def validate_nemotron_parse_endpoint_list(invoke_url: str | None) -> tuple[str, ...]:
"""Normalize and validate a Nemotron Parse endpoint list.
Args:
invoke_url: A comma-separated endpoint list, or ``None``.
Returns:
The normalized, nonempty endpoints.
Raises:
ValueError: If the list mixes NVIDIA Build and self-hosted endpoints.
"""
```
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "Reject mixed Nemotron Parse endpoint con..." | Re-trigger Greptile
| "`method='nemotron_parse'`; Parse-specific configuration is otherwise ignored." | ||
| ) | ||
| if self.method == "nemotron_parse": | ||
| validate_nemotron_parse_endpoint_list(self.nemotron_parse_invoke_url or self.invoke_url) |
There was a problem hiding this comment.
Whitespace alias bypasses validation
When nemotron_parse_invoke_url contains only whitespace and invoke_url contains mixed endpoints, raw truthiness validates the empty primary value instead of the effective fallback list, so ExtractParams construction succeeds instead of raising the required validation error.
| validate_nemotron_parse_endpoint_list(self.nemotron_parse_invoke_url or self.invoke_url) | |
| validate_nemotron_parse_endpoint_list( | |
| self.nemotron_parse_invoke_url | |
| if str(self.nemotron_parse_invoke_url or "").strip() | |
| else self.invoke_url | |
| ) |
Knowledge Base Used:
Prompt To Fix With AI
This is a comment left during a code review.
Path: nemo_retriever/src/nemo_retriever/common/params/models.py
Line: 586
Comment:
**Whitespace alias bypasses validation**
When `nemotron_parse_invoke_url` contains only whitespace and `invoke_url` contains mixed endpoints, raw truthiness validates the empty primary value instead of the effective fallback list, so `ExtractParams` construction succeeds instead of raising the required validation error.
```suggestion
validate_nemotron_parse_endpoint_list(
self.nemotron_parse_invoke_url
if str(self.nemotron_parse_invoke_url or "").strip()
else self.invoke_url
)
```
**Knowledge Base Used:**
- [Operators](https://app.greptile.com/nvidia-public-github/-/custom-context/knowledge-base/nvidia/nemo-retriever/-/docs/operators.md)
- [VDB and Common Infrastructure](https://app.greptile.com/nvidia-public-github/-/custom-context/knowledge-base/nvidia/nemo-retriever/-/docs/vdb-and-common.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| def validate_nemotron_parse_endpoint_list(invoke_url: str | None) -> tuple[str, ...]: | ||
| """Normalize Parse endpoints and reject mixed NVIDIA Build/self-hosted lists.""" |
There was a problem hiding this comment.
Validator contract lacks documentation
The new public helper does not document its parameter, normalized tuple return value, or mixed-endpoint ValueError, leaving callers without the required public interface contract.
| def validate_nemotron_parse_endpoint_list(invoke_url: str | None) -> tuple[str, ...]: | |
| """Normalize Parse endpoints and reject mixed NVIDIA Build/self-hosted lists.""" | |
| def validate_nemotron_parse_endpoint_list(invoke_url: str | None) -> tuple[str, ...]: | |
| """Normalize and validate a Nemotron Parse endpoint list. | |
| Args: | |
| invoke_url: A comma-separated endpoint list, or ``None``. | |
| Returns: | |
| The normalized, nonempty endpoints. | |
| Raises: | |
| ValueError: If the list mixes NVIDIA Build and self-hosted endpoints. | |
| """ |
Rule Used: Public modules, classes, and functions must have d... (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: nemo_retriever/src/nemo_retriever/common/params/utils.py
Line: 16-17
Comment:
**Validator contract lacks documentation**
The new public helper does not document its parameter, normalized tuple return value, or mixed-endpoint `ValueError`, leaving callers without the required public interface contract.
```suggestion
def validate_nemotron_parse_endpoint_list(invoke_url: str | None) -> tuple[str, ...]:
"""Normalize and validate a Nemotron Parse endpoint list.
Args:
invoke_url: A comma-separated endpoint list, or ``None``.
Returns:
The normalized, nonempty endpoints.
Raises:
ValueError: If the list mixes NVIDIA Build and self-hosted endpoints.
"""
```
**Rule Used:** Public modules, classes, and functions must have d... ([source](.greptile))
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Summary
nemotron_parse_modelExtractParamsconstruction and retain defense-in-depth checks for direct actor, resolver, and page invocation pathsNIMClientallocation or any request is sentRoot cause
The SDK applies one global model ID and request contract to the entire comma-separated endpoint list. NVIDIA Build requires
nvidia/nemotron-parsewith the hosted tool-call contract, while a self-hosted Parse NIM requires its versioned model ID and tagged contract. No explicitnemotron_parse_modelcan satisfy both endpoint types.The prior resolver rejected mixed lists only when the model was omitted, so an explicit model allowed an unusable configuration to proceed and fail according to endpoint selection.
Contract decision and impact
This implements the safe existing-API contract: endpoint lists must be homogeneous. Mixed Build/self-hosted lists now fail deterministically during configuration with an actionable error that explains the incompatible contracts and recommends separate ingestors or workflows. Build-only and self-hosted-only lists keep their existing behavior.
Validation
pre-commit run --all-filesgit diff --check