Add MemMachine memory integration for NeMo Agent toolkit#1460
Add MemMachine memory integration for NeMo Agent toolkit#1460Charlie-Yi-2002 wants to merge 13 commits intoNVIDIA:developfrom
Conversation
|
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughExtensive updates reorganizing packages (profiler migration from eval to standalone), implementing per-user MCP authentication patterns, removing the profiler_agent example, standardizing documentation formatting, enhancing CI/CD infrastructure with model health checks and Slack integration, and updating configuration policies for dependency management. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Suggested labels
✨ Finishing Touches🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 16
🤖 Fix all issues with AI agents
In `@packages/nvidia_nat_memmachine/pyproject.toml`:
- Around line 16-25: Update package dependency lists: in
packages/nvidia_nat_all/pyproject.toml add "nvidia-nat-memmachine" (no version
constraint) to the dependencies array, and in
packages/nvidia_nat_memmachine/pyproject.toml change the memmachine-server entry
from "memmachine-server~=0.2.2" to "memmachine-server~=0.2.1" so the declared
dependency matches the published version; ensure the dependencies remain sorted
per the file comments.
In
`@packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memmachine_editor.py`:
- Around line 1-9: Add the standard SPDX Apache-2.0 license header to the top of
memmachine_editor.py (above all imports); ensure the exact SPDX short-form line
"SPDX-License-Identifier: Apache-2.0" is present and include any required
copyright owner/year line per project policy so the file containing imports like
asyncio, requests, MemoryType, MemoryEditor, and MemoryItem is properly
licensed.
- Around line 185-196: The add_memory() closure captures outer loop variables
(memory, memory_text, metadata, memory_types) by reference so all scheduled
tasks use the last values; fix by binding those values into the closure before
scheduling (e.g., define add_memory(memory=memory, memory_text=memory_text,
metadata=metadata, memory_types=memory_types): or use functools.partial to bind
arguments) so the memory.add(...) call inside add_memory uses the per-iteration
values when you call task = asyncio.to_thread(add_memory).
- Around line 299-304: The bare except in the episodic_by_conversation loop
around conv_episodes.sort hides real errors; replace it with a targeted
exception handler that catches likely errors (e.g., TypeError, AttributeError,
ValueError) and log the failure including conv_key and the exception before
continuing. Specifically, wrap the conv_episodes.sort(key=lambda e:
e.get("created_at") or e.get("timestamp") or "") call in an except (TypeError,
AttributeError, ValueError) as e block and emit a warning or error via the
module's logger (or logging.warning) referencing conv_key and e so issues aren't
silently swallowed.
In `@packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memory.py`:
- Around line 85-88: The except block in the project-creation fallback (inside
memory.py where the try/except around client/project creation is located)
currently swallows all exceptions with "pass"; replace that with a
logger.exception(...) call to record the full stack trace and context (e.g.,
"Failed to create project, falling back to client usage") so debugging info is
preserved; keep the existing fallback behavior (do not re-raise) but ensure the
exception is logged via logger.exception in the except Exception as e: handler.
In `@packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/register.py`:
- Line 1: Add the standard SPDX Apache-2.0 license header at the top of this
file (register.py) before any code — ensure the file begins with the SPDX
license identifier (e.g., a comment containing "SPDX-License-Identifier:
Apache-2.0") so the header appears above the existing import line "from . import
memory"; update only the file header area to include the required license
comment.
In `@packages/nvidia_nat_memmachine/tests/API_CALL_VERIFICATION.md`:
- Around line 1-5: Add the standard SPDX Apache-2.0 license header as the very
first line of the markdown file (API_CALL_VERIFICATION.md) by inserting
"SPDX-License-Identifier: Apache-2.0" at the top of the file so the file now
begins with that license identifier.
In `@packages/nvidia_nat_memmachine/tests/test_add_and_retrieve.py`:
- Around line 1-24: Add the missing SPDX Apache-2.0 license header at the top of
the file (above the docstring or immediately after the shebang) to satisfy
licensing requirements, and mark the integration test with pytest by importing
pytest and decorating the test function (e.g., test_add_and_retrieve) with
`@pytest.mark.integration` so external-service tests are properly classified;
update imports to include "import pytest" and ensure the decorator is applied to
the test function in the script.
In `@packages/nvidia_nat_memmachine/tests/test_memmachine_api_calls.py`:
- Around line 1-2: Update the SPDX header years in the file's top comment lines:
change the copyright year range in the SPDX-FileCopyrightText line (currently
"2024-2025") to include 2026 (e.g., "2024-2026") and ensure the
SPDX-License-Identifier line remains unchanged; edit the two header comment
lines at the top of the file to reflect the new year range.
- Line 366: The assignment to results from calling editor_with_spy.search is
unused and should be removed to avoid lint warnings; simply call await
editor_with_spy.search(...) without assigning its return, or if you prefer
preserving a placeholder, assign to _ (underscore) instead—update the call site
where results is assigned in the test (the await editor_with_spy.search
invocation) to drop the unused variable.
- Line 50: Update the signature of get_calls to use explicit PEP 604 union
typing for the optional parameter: replace the parameter declaration
method_name: str = None with method_name: str | None, and ensure any related
type hints or usages in the get_calls function body or its callers remain valid
with the new annotation.
In `@packages/nvidia_nat_memmachine/tests/test_memmachine_integration.py`:
- Around line 173-184: The for-loop in test_memmachine_integration.py uses an
unused loop variable named "attempt" which triggers a lint warning; rename it to
"_attempt" in both occurrences (the loop that calls memory_client.search with
query="morning work allergy peanuts" and the similar loop around lines ~403-414)
so the intent is preserved and the linter is satisfied, keeping the loop logic
and the await asyncio.sleep(2) retry behavior unchanged.
- Around line 1-2: Update the SPDX header year range in the file's top comment
to include 2026: locate the SPDX lines at the top of the file (the
SPDX-FileCopyrightText and SPDX-License-Identifier header) and change the
copyright year range "2024-2025" to "2024-2026" so the notice accurately
reflects the file modification year.
- Around line 22-25: Update the module docstring in the
tests/test_memmachine_integration.py file to wrap code entities in backticks to
satisfy Vale and docstring rules: surround MemMachine server with `MemMachine`,
the environment variable name with `MEMMACHINE_BASE_URL`, and the test command
with backticks like `pytest tests/test_memmachine_integration.py -v`; ensure any
other inline code-like tokens in that docstring are also backticked.
In `@packages/nvidia_nat_memmachine/tests/test_memory.py`:
- Around line 1-2: Update the SPDX header year range in the file header comment
to include 2026; specifically modify the top two comment lines (the SPDX
copyright and SPDX-License-Identifier block) so the year range reads "2024-2026"
instead of "2024-2025" to reflect the file modification in 2026.
- Around line 155-159: The test test_memmachine_memory_client_config_validation
currently catches a broad Exception when constructing
MemMachineMemoryClientConfig; change the assertion to catch the specific
pydantic validation error by replacing pytest.raises(Exception) with
pytest.raises(ValidationError) and add the necessary import for ValidationError
from pydantic so the test asserts the concrete validation failure from
MemMachineMemoryClientConfig.
🧹 Nitpick comments (7)
packages/nvidia_nat_memmachine/src/nat/meta/pypi.md (1)
20-24: Capitalize "Toolkit" in the heading.Per coding guidelines, titles/headings should use "Toolkit" (capital T) while body text uses "toolkit" (lowercase t). Also ensure the file ends with a single newline.
📝 Suggested fix
-# NVIDIA NeMo Agent toolkit Subpackage +# NVIDIA NeMo Agent Toolkit Subpackage This is a subpackage for MemMachine memory integration in NeMo Agent toolkit. For more information about the NVIDIA NeMo Agent toolkit, please visit the [NeMo Agent toolkit GitHub Repo](https://github.com/NVIDIA/NeMo-Agent-Toolkit). +packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memory.py (3)
41-42: Add return type annotation and consider documenting unusedbuilderparameter.Per coding guidelines, public APIs require type hints on return values. The function should declare its return type. The
builderparameter appears unused (flagged by static analysis) — if it's required by the@register_memorydecorator contract, consider adding a comment or using_prefix to indicate intentional non-use.📝 Suggested fix
+from collections.abc import AsyncGenerator +from typing import Any + `@register_memory`(config_type=MemMachineMemoryClientConfig) -async def memmachine_memory_client(config: MemMachineMemoryClientConfig, builder: Builder): +async def memmachine_memory_client( + config: MemMachineMemoryClientConfig, + builder: Builder, # Required by `@register_memory` contract, unused here +) -> AsyncGenerator[Any, None]:
34-38: Clarify the distinction betweenmax_retriesandnum_retriesfromRetryMixin.The class defines
max_retriesfor SDK-level retries, while inheritingnum_retriesfromRetryMixin(used at line 95 forpatch_with_retry). This dual retry configuration may confuse users. Consider adding a note in the docstring explaining when each is used.📝 Suggested docstring addition
""" Configuration for MemMachine memory client. Based on the MemMachine Python SDK as documented at: https://github.com/MemMachine/MemMachine/blob/main/docs/examples/python.mdx Note: This integration is for local/self-hosted MemMachine instances. LLM API keys (e.g., OpenAI) are configured in the MemMachine cfg.yml file, not in this client configuration. + + Retry behavior: + - `max_retries`: SDK-level retries for individual MemMachine API calls. + - `num_retries` (inherited from RetryMixin): Application-level retries with + status code filtering, applied to the memory editor wrapper. """
92-98: Redundantisinstancecheck —configalways inherits fromRetryMixin.Since
MemMachineMemoryClientConfiginherits fromRetryMixin, this check is alwaysTrue. Consider removing the check for clarity, or add a comment if this is intentional defensive coding for future flexibility.📝 Suggested simplification
- if isinstance(config, RetryMixin): - memory_editor = patch_with_retry( - memory_editor, - retries=config.num_retries, - retry_codes=config.retry_on_status_codes, - retry_on_messages=config.retry_on_errors - ) + memory_editor = patch_with_retry( + memory_editor, + retries=config.num_retries, + retry_codes=config.retry_on_status_codes, + retry_on_messages=config.retry_on_errors + )packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memmachine_editor.py (1)
471-490: Unused variabledelete_semanticand incomplete bulk deletion path.The variable
delete_semanticis assigned but never used. If bulk deletion should respect this flag in the future, consider either implementing partial support or removing the variable to avoid confusion.Proposed fix - remove unused variable
project_id = kwargs.pop("project_id", None) org_id = kwargs.pop("org_id", None) - delete_semantic = kwargs.pop("delete_semantic_memory", False) # Note: MemMachine SDK doesn't have a delete_all methodpackages/nvidia_nat_memmachine/memmachine_memory_example.ipynb (1)
386-403: Consider usinghttpxfor consistency with coding guidelines.The coding guidelines prefer
httpxoverrequests. Whilerequestsworks fine here for a simple health check, consider aligning with the codebase convention.packages/nvidia_nat_memmachine/tests/test_add_and_retrieve.py (1)
179-183: Uselogger.exception()when catching and logging exceptions without re-raising.Per coding guidelines, when catching and logging exceptions without re-raising, use
logger.exception()to capture full stack trace. The current approach usingtraceback.print_exc()works but doesn't follow the project's logging conventions.
packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memmachine_editor.py
Show resolved
Hide resolved
packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memmachine_editor.py
Outdated
Show resolved
Hide resolved
packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memmachine_editor.py
Outdated
Show resolved
Hide resolved
packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memory.py
Outdated
Show resolved
Hide resolved
packages/nvidia_nat_memmachine/tests/test_memmachine_integration.py
Outdated
Show resolved
Hide resolved
packages/nvidia_nat_memmachine/tests/test_memmachine_integration.py
Outdated
Show resolved
Hide resolved
packages/nvidia_nat_memmachine/tests/test_memmachine_integration.py
Outdated
Show resolved
Hide resolved
willkill07
left a comment
There was a problem hiding this comment.
Thank you for your contribution!
This needs some work, and I'm going to start with the low-hanging fruit and a quick review before addressing the files that GitHub hid by default due to size.
Overall, all comments by coderabbit and additional ones from me need to be addressed.
Additionally, copyright headers for new files should include the current year rather than 2024-2025
I will admit I don't know how many commits behind develop you are, but you should assume a base as being near or close to top of tree.
This is my own opinion here, but I also don't like the idea of mandating a local server. Is there not an API/microservice that can be used instead?
Finally, if you have any questions don't hesitate to ask!
packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memmachine_editor.py
Show resolved
Hide resolved
packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/register.py
Outdated
Show resolved
Hide resolved
packages/nvidia_nat_memmachine/tests/test_memmachine_integration.py
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/nvidia_nat_all/pyproject.toml (1)
23-33: Addnvidia-nat-memmachineto the workspace sources (and syncuv.lock).Since this dependency is a workspace package, it should be listed in
[tool.uv.sources]to ensure local resolution. Also make sureuv.lockis updated to reflect the new dependency.🧩 Proposed update
[tool.uv.sources] nvidia-nat = { workspace = true } nvidia-nat-agno = { workspace = true } nvidia-nat-autogen = { workspace = true } nvidia-nat-crewai = { workspace = true } nvidia-nat-langchain = { workspace = true } nvidia-nat-llama-index = { workspace = true } nvidia-nat-mcp = { workspace = true } nvidia-nat-mem0ai = { workspace = true } +nvidia-nat-memmachine = { workspace = true } nvidia-nat-mysql = { workspace = true }Based on learnings.
🤖 Fix all issues with AI agents
In
`@packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memmachine_editor.py`:
- Around line 324-331: In the try/except around conv_episodes.sort in
memmachine_editor (the block catching TypeError/AttributeError/ValueError for
conv_key), replace the logger.warning call with logger.exception so the full
stack trace is preserved when the sort fails; keep the same descriptive message
referencing conv_key and that we are "continuing without sorting" but call
logger.exception(...) instead of logger.warning(...).
- Around line 29-45: The docstring for the MemMachineEditor class contains
several metadata keys and code entities that are not formatted as inline code;
update the MemMachineEditor docstring so all code identifiers (e.g., MemoryItem,
and metadata keys `session_id`, `agent_id`, `group_id`, `project_id`, `org_id`,
and the class name `MemMachineClient` reference) are wrapped in backticks to
satisfy Vale/coding guidelines and ensure clarity; keep the explanatory text
unchanged and only modify the docstring formatting around these identifiers.
- Around line 179-190: The closure add_memory currently captures the outer
variable memory by reference, causing deferred asyncio.to_thread tasks to all
use the last memory instance; fix this by binding memory into the closure
signature as a default parameter (e.g., add a parameter like memory=memory) so
each add_memory captures its own memory instance before scheduling; update the
add_memory definition that calls memory.add(...) to include memory as a default
arg consistent with the identical pattern used in the other branch.
In `@packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memory.py`:
- Around line 48-51: The function signature for memmachine_memory_client
currently defines an unused parameter named builder which ruff flags; silence it
by renaming builder to _builder (or alternatively append a per-argument lint
suppression like "# noqa: ARG001") in the memmachine_memory_client definition so
the parameter remains for the `@register_memory` contract but no lint error is
raised.
- Around line 55-62: The project incorrectly requires the server package while
code imports the client: update the dependency in pyproject.toml from
memmachine-server to memmachine-client, and update the ImportError text in
memory.py (the block that catches ImportError for "from memmachine import
MemMachineClient") to instruct installing memmachine-client (e.g., "pip install
memmachine-client") and adjust any package name references/links so they point
to the client package documentation; keep the rest of the error message
structure (include the caught exception e) intact.
In `@packages/nvidia_nat_memmachine/tests/test_add_and_retrieve.py`:
- Around line 199-202: Replace the logger.exception call in the except block
that captures "Exception as e" with logger.error(..., exc_info=True) so the
error message is logged with the traceback without duplicating stack traces on
re-raise; specifically, locate the except Exception as e block (where
logger.exception("Error during test execution") is called) and change it to log
the same message using logger.error("Error during test execution",
exc_info=True) before re-raising the exception.
In `@packages/nvidia_nat_memmachine/tests/test_memmachine_integration.py`:
- Around line 68-85: The two pytest fixture functions lack return type
annotations; update test_config_fixture to declare a return type of
MemMachineMemoryClientConfig (i.e., def test_config_fixture(...) ->
MemMachineMemoryClientConfig:) and update test_user_id_fixture to declare a
return type of str (def test_user_id_fixture(...) -> str:); ensure the
MemMachineMemoryClientConfig symbol is imported or referenced correctly in the
test module if not already.
- Around line 88-156: The async test function
test_add_and_retrieve_conversation_memory is missing the pytest-asyncio marker;
add `@pytest.mark.asyncio` above the function (place it directly after
`@pytest.mark.slow`) so pytest-asyncio runs the async test correctly.
- Around line 49-65: Change the broad except Exception in the MemMachineClient
health-check block to catch the specific requests exception type raised by the
client (e.g., requests.exceptions.RequestException or requests.RequestException)
so real errors aren't swallowed; import the exception from requests at top if
needed and keep the same behavior of raising RuntimeError when fail_missing is
true or calling pytest.skip otherwise while still preserving the existing
ImportError handling for the memmachine import and the use of
MemMachineClient.health_check().
♻️ Duplicate comments (2)
packages/nvidia_nat_memmachine/tests/test_add_and_retrieve.py (1)
46-209: Avoid running live MemMachine calls in the default test suite.
test_add_and_retrieveis still a discovered test and will run without the integration marker, even though it requires a live MemMachine instance. Make it a helper (non-test) or mark it as integration to keep it out of default runs.✅ Suggested restructuring
-async def test_add_and_retrieve(): +async def _run_add_and_retrieve(): """Test adding memories and retrieving them.""" @@ -@pytest.mark.integration -async def test_add_and_retrieve_integration(): +@pytest.mark.integration +async def test_add_and_retrieve_integration(): """Integration test for adding and retrieving memories.""" - await test_add_and_retrieve() + await _run_add_and_retrieve() @@ -if __name__ == "__main__": - asyncio.run(test_add_and_retrieve()) +if __name__ == "__main__": + asyncio.run(_run_add_and_retrieve())As per coding guidelines.
packages/nvidia_nat_memmachine/tests/test_memmachine_integration.py (1)
16-24: Backtick code-like tokens in the module/fixture docstrings.The docstrings still leave code entities and the localhost URL unformatted, which can trigger Vale. Please wrap them in backticks for consistency. As per coding guidelines, please wrap code entities in backticks.
✍️ Proposed fix
-Integration tests for MemMachine memory integration. +Integration tests for `MemMachine` memory integration. @@ -Set `MEMMACHINE_BASE_URL` environment variable to override default (http://localhost:8080). +Set `MEMMACHINE_BASE_URL` environment variable to override default (`http://localhost:8080`). @@ -Set MEMMACHINE_BASE_URL environment variable to override default (http://localhost:8080). +Set `MEMMACHINE_BASE_URL` environment variable to override default (`http://localhost:8080`).Also applies to: 39-44
packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memmachine_editor.py
Show resolved
Hide resolved
packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memmachine_editor.py
Show resolved
Hide resolved
packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memmachine_editor.py
Outdated
Show resolved
Hide resolved
packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memory.py
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@packages/nvidia_nat_memmachine/tests/test_add_and_retrieve.py`:
- Around line 205-208: The async integration test function
test_add_and_retrieve_integration is missing the `@pytest.mark.asyncio` decorator;
add `@pytest.mark.asyncio` above the async def test_add_and_retrieve_integration()
declaration so pytest runs it as an async test (keep the existing
`@pytest.mark.integration` marker and the call to await test_add_and_retrieve()).
In `@packages/nvidia_nat_memmachine/tests/test_memmachine_editor.py`:
- Around line 1-2: Update the SPDX copyright header lines to include 2026 by
changing the year range in the two SPDX comment lines: adjust the copyright
comment line that currently reads "2024-2025" to "2024-2026" and keep the
SPDX-License-Identifier line as-is; ensure these changes are applied at the top
of the file where the SPDX header is defined.
🧹 Nitpick comments (2)
packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memmachine_editor.py (1)
322-329: Remove redundant exception object fromlogger.exceptioncall.
logger.exception()automatically includes the exception information, so including{e}in the message is redundant.Proposed fix
except (TypeError, AttributeError, ValueError) as e: # Skip sorting if timestamps are missing or incompatible logger.exception( - f"Failed to sort episodes for conversation '{conv_key}': {e}. " + f"Failed to sort episodes for conversation '{conv_key}'. " "Continuing without sorting." )packages/nvidia_nat_memmachine/tests/test_memmachine_integration.py (1)
116-118: Consider movingasyncioimport to module level.The
asynciomodule is imported inside multiple test functions. Moving it to the top of the file with other imports would be cleaner.Proposed fix
Add to imports at top of file:
import asyncioThen remove the inline imports in each test function.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/nvidia_nat_memmachine/tests/test_memmachine_editor.py`:
- Around line 492-496: The mock return for mock_memory_instance.search is
inconsistent with other tests: instead of assigning a plain dict set
mock_memory_instance.search.return_value to a Mock (or MagicMock) instance whose
.content attribute contains the dict used in other tests (e.g.,
{"episodic_memory": [], "semantic_memory": [], "episode_summary": []}), so that
MemMachineEditor.search (and any code accessing result.content) behaves
consistently; update the test to wrap the dict in a Mock with .content and
adjust any assertions if they expect the Mock shape.
🧹 Nitpick comments (1)
packages/nvidia_nat_memmachine/tests/test_memmachine_editor.py (1)
178-202: Consider removing unused fixture parameters.The
mock_clientandmock_projectparameters are injected but not used in the test body. Pytest automatically instantiates the fixture dependency chain whenmemmachine_editor_with_clientis requested, so you only need to explicitly request fixtures you directly interact with.This pattern appears in several tests:
test_add_items_with_direct_memory,test_add_items_with_memory_text_only,test_search_success,test_remove_items_by_memory_id_episodic,test_remove_items_by_memory_id_semantic,test_add_items_with_custom_project_and_org, andtest_search_with_custom_project_and_org.♻️ Example fix for this test
async def test_add_items_with_direct_memory( memmachine_editor_with_client: MemMachineEditor, - mock_client: Mock, - mock_project: Mock, mock_memory_instance: Mock, sample_direct_memory_item: MemoryItem ):
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/nvidia_nat_memmachine/tests/test_add_and_retrieve.py`:
- Around line 111-193: Add assertions after each search to validate results: for
Test 1 (first retrieval) assert retrieved is non-empty and that
retrieved[0].memory or retrieved[0].conversation contains an expected
substring/tag; for Test 2 (direct_memory) assert the search result length > 0
and that at least one result's memory includes "allergic to peanuts" or has tags
containing "allergy"/"preference"; for Test 3 (multiple_memories) assert
len(all_memories) >= 3 and that tags include "fact_1"/"fact_2"/"fact_3". Place
these assertions immediately after the corresponding memory_client.search calls
that populate retrieved and all_memories (use the MemoryItem,
memory_client.search, memory_client.add_items, user_id/session_id/agent_id
variables to locate the sections).
🧹 Nitpick comments (1)
packages/nvidia_nat_memmachine/tests/test_add_and_retrieve.py (1)
98-100: Replace fixed sleeps with polling + timeout to reduce flakiness.A hardcoded 2‑second wait can be too short or unnecessarily long depending on load. Consider polling the search until results appear (bounded by a timeout) to make the test deterministic.
Also applies to: 135-136, 175-176
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@packages/nvidia_nat_memmachine/memmachine_memory_example.ipynb`:
- Around line 108-113: Update the markdown text to remove possessive
constructions for inanimate objects: change "MemMachine's LLM provider API keys
(e.g., OpenAI) are configured in the MemMachine `cfg.yml` file, not here." to a
non-possessive form such as "LLM provider API keys for MemMachine (e.g., OpenAI)
are configured in the MemMachine `cfg.yml` file, not here." and apply the same
change to the other occurrence referenced (around lines 575-579) so all
instances use "for MemMachine" or "the MemMachine" instead of "MemMachine’s".
In `@packages/nvidia_nat_memmachine/tests/test_add_and_retrieve.py`:
- Around line 59-67: The helper function currently named test_add_and_retrieve
(which pytest will collect) should be renamed to _run_add_and_retrieve to avoid
double test collection; update the function definition name and every call site
(e.g., change calls in test_add_and_retrieve_integration or any other tests that
invoke test_add_and_retrieve to call _run_add_and_retrieve instead) so tests
still execute the helper but pytest won't treat it as a standalone test.
In `@packages/nvidia_nat_memmachine/tests/test_memmachine_editor.py`:
- Around line 178-184: The test function test_add_items_with_direct_memory
currently declares fixture parameters that are only used for setup and trigger
ruff ARG001; update the function signature to silence unused-fixture warnings by
prefixing unused fixtures with an underscore (e.g., change mock_client,
mock_project, mock_memory_instance to _mock_client, _mock_project,
_mock_memory_instance) or alternatively append "# noqa: ARG001" if you prefer a
comment; ensure you only rename the fixtures in the test function signature
(leave the fixture definitions intact) so references to
test_add_items_with_direct_memory still run correctly.
In `@packages/nvidia_nat_memmachine/tests/test_memory.py`:
- Around line 19-23: This module contains multiple async test functions but
lacks the pytest-asyncio marker; add a module-level marker by inserting
pytestmark = pytest.mark.asyncio near the top (after the imports) so all async
tests run under pytest-asyncio, or alternatively decorate each async test with
`@pytest.mark.asyncio`; reference the existing imports (pytest, Builder,
MemMachineMemoryClientConfig, memmachine_memory_client) and place the
module-level pytestmark immediately after those imports.
🧹 Nitpick comments (2)
packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memory.py (1)
29-51: Add Google-style docstrings for the public config and factory.
memmachine_memory_clienthas no docstring and the config docstring isn’t Google‑style (Args/Returns). Please add Google‑style docstrings and wrap code entities in backticks. As per coding guidelines.packages/nvidia_nat_memmachine/tests/test_memmachine_integration.py (1)
26-36: Addasyncioto module-level imports.
asynciois imported inside multiple test functions (lines 117, 187, 269, 330, 411). Move it to the module-level imports for cleaner code.✍️ Proposed fix
import os import uuid +import asyncio import pytest import requestsThen remove the
import asynciostatements from within the test functions.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/nvidia_nat_memmachine/tests/test_memory.py`:
- Around line 105-123: The test's import_side_effect raises ImportError with a
custom message which triggers Ruff TRY003; change the raise in
import_side_effect inside test_memmachine_memory_client_import_error to raise
ImportError (no custom string) so the patch of builtins.__import__ simply raises
the exception, leaving pytest.raises to assert the expected "Could not import
MemMachineClient" from memmachine_memory_client; update import_side_effect
accordingly and keep the rest of the test (patch and async with
memmachine_memory_client) unchanged.
🧹 Nitpick comments (1)
packages/nvidia_nat_memmachine/tests/test_memory.py (1)
26-66: Align fixture function names and return type hints with test conventions.
Fixture names should use thefixture_prefix and return type hints for readability and linting consistency.♻️ Proposed refactor
`@pytest.fixture`(name="mock_builder") -def mock_builder_fixture(): +def fixture_mock_builder() -> Mock: """Fixture to provide a mocked Builder instance.""" return Mock(spec=Builder) `@pytest.fixture`(name="config") -def config_fixture(): +def fixture_config() -> MemMachineMemoryClientConfig: """Fixture to provide a MemMachineMemoryClientConfig instance.""" return MemMachineMemoryClientConfig( base_url="http://localhost:8095", org_id="test_org", project_id="test_project", timeout=30, max_retries=3 ) `@pytest.fixture`(name="config_minimal") -def config_minimal_fixture(): +def fixture_config_minimal() -> MemMachineMemoryClientConfig: """Fixture to provide a minimal MemMachineMemoryClientConfig instance.""" return MemMachineMemoryClientConfig( base_url="http://localhost:8095" ) `@pytest.fixture`(name="mock_memmachine_client") -def mock_memmachine_client_fixture(): +def fixture_mock_memmachine_client() -> Mock: """Fixture to provide a mocked MemMachineClient.""" mock_client = Mock() mock_client.base_url = "http://localhost:8095" return mock_client `@pytest.fixture`(name="mock_project") -def mock_project_fixture(): +def fixture_mock_project() -> Mock: """Fixture to provide a mocked Project instance.""" mock_project = Mock() mock_project.org_id = "test_org" mock_project.project_id = "test_project" return mock_projectAs per coding guidelines, ...
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@packages/nvidia_nat_memmachine/tests/test_add_and_retrieve.py`:
- Around line 17-24: Update the module docstring at the top of
test_add_and_retrieve.py to remove the claim that results are verified—replace
"Verifies they match" with wording that accurately states the test prints or
demonstrates API interaction without asserting retrieval correctness (e.g.,
"Prints retrieved memories to demonstrate API interaction; no correctness
assertions are performed"). Ensure the change is made in the module-level
docstring that describes the script's three-step flow so it accurately reflects
intended behavior.
- Around line 224-226: The integration test function
test_add_and_retrieve_integration should be marked as slow; add the pytest
marker by annotating the function with `@pytest.mark.slow` alongside the existing
`@pytest.mark.integration` and `@pytest.mark.asyncio` decorators so pytest can skip
it in default runs; locate the test_add_and_retrieve_integration definition in
tests/test_add_and_retrieve.py and insert `@pytest.mark.slow` above the async def.
🧹 Nitpick comments (1)
packages/nvidia_nat_memmachine/tests/test_add_and_retrieve.py (1)
51-56: Narrow exception handling in health check.Catching
Exceptionwill hide unexpected errors and can cause silent skips. Prefer arequests.RequestExceptioncatch so genuine bugs still surface.♻️ Proposed change
- except Exception: + except requests.RequestException: return False
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/nvidia_nat_memmachine/tests/test_add_and_retrieve.py`:
- Around line 38-56: The test is missing the pytest slow marker and
_memmachine_available() is blocking the event loop by using requests.get; change
_memmachine_available to be async (async def _memmachine_available(base_url:
str) -> bool), switch the synchronous requests call to an async httpx client
(use httpx.AsyncClient and await the GET to f"{base_url}/api/v2/health" with
timeout), narrow the caught exception to httpx.RequestError (or httpx.HTTPError)
instead of Exception, and add `@pytest.mark.slow` to the test function that relies
on this helper so the test is correctly marked as slow.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/nvidia_nat_memmachine/pyproject.toml`:
- Around line 1-3: Add the SPDX Apache-2.0 header as the very first lines of the
file and update the copyright year to the current year; specifically insert the
standard SPDX header above the existing [build-system] section so the file
begins with the license header followed by the existing build-backend and
requires lines.
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@packages/nvidia_nat_memmachine/README.md`:
- Line 69: Update the heading text "Usage in NeMo Agent toolkit" to use a
capital T for "Toolkit" so it reads "Usage in NeMo Agent Toolkit"; locate the
heading in packages/nvidia_nat_memmachine/README.md (the line with the string
"Usage in NeMo Agent toolkit") and modify only that heading text to follow the
project's MD casing convention.
- Line 1: The title line "# NVIDIA NeMo Agent toolkit - MemMachine Integration"
should use "Toolkit" with a capital T; update the heading text (the top-level
markdown heading) to "# NVIDIA NeMo Agent Toolkit - MemMachine Integration" so
the title follows the capitalization guideline while leaving the rest of the
README content unchanged.
- Line 1: Add the required SPDX Apache-2.0 header to the top of the README.md
file: insert the SPDX header comment (e.g. "SPDX-FileCopyrightText: <copyright
holder>" and "SPDX-License-Identifier: Apache-2.0") as the first lines of
packages/nvidia_nat_memmachine/README.md so the file begins with the required
license metadata for md/mdx files.
- Around line 50-65: Update the incorrect default port statement in the README:
change the sentence that currently reads "The server will start on
`http://localhost:8095` by default" to state the actual default
`http://localhost:8080` (or explicitly say "`http://localhost:8080` by default,
or the port you configured") and, if keeping the recommendation, clarify that
`8095` is only a suggested custom port; locate and edit the paragraph following
the memmachine-server usage example to make this correction.
|
Thanks for going through my feedback. We have a bit of a backlog and some churn on work right now, so it may take me a couple days to give this another pass. |
No worries, let me know whenever you have time which other things need to be addressed! |
|
@Charlie-Yi-2002 Could you address the merge conflicts and ensure that DCO passes (all of your commits must be signed). |
@willkill07 I addressed the merge conflict. I'm a little confused on the DCO checks. It lists [19f7193], [3a7c40e], [07ff4df] as not having a signoff but when I checked the commit history, they all have the verified symbol and say it was signed off by me. Not sure if I'm misinterpreting what the DCO is checking for ? |
|
@Charlie-Yi-2002 Please see: https://github.com/NVIDIA/NeMo-Agent-Toolkit/pull/1460/checks?check_run_id=63168815034 All commits need to be signed off via There should be a line in the commit messages that says: There is guidance in the above link. If it's easier to push a clean history for this branch with a single commit, that's also okay. |
2443acd to
d6f05e6
Compare
@willkill07 Fixed the DCO issue. Let me know if there's any other changes I need to make. Thanks! |
@willkill07 Sorry just saw your comment today. I believe I fixed the failed CI checks. Still failed on the
|
ed441b0 to
c6ad5b5
Compare
|
/ok to test c6ad5b5 |
|
Please add/commit the package-specific |
|
/ok to test ffff07e |
cdd45e1 to
837c0db
Compare
|
/ok to test 929d308 |
|
@willkill07 I changed the python dependency to 3.12+. Thanks for letting me know. |
|
/ok to test 301907a |
Sorry, I don't think we understood this at the same level. Currently we mandate that everything within the toolkit supports Python 3.11, 3.12, and 3.13. As you can see from CI running, CI isn't handled to not support a subpackage. Additionally, documentation is failing. Either |
Ok I see what you mean. Currently memmachine-client supports 3.10+ but it bundles some of the memmachine-server code (even though it's not used) and memmachine-server uses 3.12+. We have a PR out on our side to decouple the packages. Let me talk with my team to see if we can get that released earlier. |
Signed-off-by: Charlie Yi <charlie.yi@memverge.com>
…t the end of file Signed-off-by: Charlie Yi <charlie.yi@memverge.com>
Co-authored-by: Will Killian <2007799+willkill07@users.noreply.github.com> Signed-off-by: Charlie-Yi-2002 <charlie.yi@memverge.com>
Co-authored-by: Will Killian <2007799+willkill07@users.noreply.github.com> Signed-off-by: Charlie-Yi-2002 <charlie.yi@memverge.com>
Signed-off-by: Charlie Yi <charlie.yi@memverge.com>
Signed-off-by: Charlie Yi <charlie.yi@memverge.com>
Signed-off-by: Charlie Yi <charlie.yi@memverge.com>
Signed-off-by: Charlie Yi <charlie.yi@memverge.com>
Signed-off-by: Charlie Yi <charlie.yi@memverge.com>
Signed-off-by: Charlie Yi <charlie.yi@memverge.com>
…, remove test for memmachine import since no longer relevant, update indentation Signed-off-by: Charlie Yi <charlie.yi@memverge.com>
Signed-off-by: Charlie Yi <charlie.yi@memverge.com>
There was a problem hiding this comment.
Actionable comments posted: 6
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
docs/source/run-workflows/observe/observe-workflow-with-weave.md (1)
18-18:⚠️ Potential issue | 🟡 MinorUse the required product name format in the page title.
Please include “NVIDIA NeMo Agent Toolkit” in the document title to match docs naming conventions for titles/webpages.
As per coding guidelines:
docs/source/**/*.md: "Use 'NVIDIA NeMo Agent Toolkit' for document titles and webpages."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/source/run-workflows/observe/observe-workflow-with-weave.md` at line 18, The page title "# Observing a Workflow with W&B Weave" does not follow the required product-name format; update the Markdown title to include "NVIDIA NeMo Agent Toolkit" (for example, change the header to include "NVIDIA NeMo Agent Toolkit — Observing a Workflow with W&B Weave" or similar) so the document title complies with the docs/source/**/*.md naming guideline; modify the title line in this file accordingly..pre-commit-config.yaml (1)
33-62:⚠️ Potential issue | 🟠 MajorAdd missing
uv-lockhook forpackages/nvidia_nat_memmachine.The new package is not included in the per-package
uv-lockhooks, so lockfile enforcement for MemMachine can be skipped and CI can fail on lock checks.Proposed fix
- { id: uv-lock, name: "uv-lock-mcp", args: [--project, packages/nvidia_nat_mcp], files: "packages/nvidia_nat_mcp/pyproject.toml" } - { id: uv-lock, name: "uv-lock-mem0ai", args: [--project, packages/nvidia_nat_mem0ai], files: "packages/nvidia_nat_mem0ai/pyproject.toml" } + - { id: uv-lock, name: "uv-lock-memmachine", args: [--project, packages/nvidia_nat_memmachine], files: "packages/nvidia_nat_memmachine/pyproject.toml" } - { id: uv-lock, name: "uv-lock-mysql", args: [--project, packages/nvidia_nat_mysql], files: "packages/nvidia_nat_mysql/pyproject.toml" }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.pre-commit-config.yaml around lines 33 - 62, Add a new uv-lock hook entry for the MemMachine package to the per-package hooks block: create a line similar to the other entries using id: uv-lock, name: "uv-lock-memmachine", args: [--project, packages/nvidia_nat_memmachine], files: "packages/nvidia_nat_memmachine/pyproject.toml" so that the uv-lock hook (like "uv-lock-mem0ai"/"uv-lock-core") enforces the lockfile for packages/nvidia_nat_memmachine.docs/source/improve-workflows/evaluate.md (1)
22-22:⚠️ Potential issue | 🟡 MinorCapitalize 'Toolkit' in subsequent references.
The term "the toolkit" should use a capital 'T'. Based on learnings, starting from commit 37d9f33 (Jan 29, 2026), the lowercase 'toolkit' should no longer be used in body text, titles, or headings.
📝 Proposed fix
-NeMo Agent Toolkit provides a set of evaluators to run and evaluate workflows. In addition to the built-in evaluators, the toolkit provides a plugin system to add custom evaluators. +NeMo Agent Toolkit provides a set of evaluators to run and evaluate workflows. In addition to the built-in evaluators, the Toolkit provides a plugin system to add custom evaluators.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/source/improve-workflows/evaluate.md` at line 22, Update all occurrences of the lowercase phrase "the toolkit" to "the Toolkit" in this document; specifically change the sentence that follows "NeMo Agent Toolkit provides a set of evaluators..." so it reads "...the Toolkit provides a plugin system to add custom evaluators." Search for any other instances of "toolkit" in this file and capitalize them to "Toolkit" to match the new style guideline.
🟡 Minor comments (15)
docs/source/improve-workflows/finetuning/dpo_with_nemo_customizer.md-383-383 (1)
383-383:⚠️ Potential issue | 🟡 MinorFix sentence fragment in
hf_tokendescription (Line 383).“Can be empty if not required.” is a fragment in the table description. Make it a full sentence for docs quality.
✏️ Suggested edit
-| `hf_token` | `str` | `""` | Hugging Face token for datastore authentication. Can be empty if not required. | +| `hf_token` | `str` | `""` | Hugging Face token for datastore authentication. It can be empty if not required. |As per coding guidelines, “Documentation must be clear and comprehensive.”
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/source/improve-workflows/finetuning/dpo_with_nemo_customizer.md` at line 383, The table entry for hf_token contains a sentence fragment; update the description for `hf_token` to a full sentence (for example: "Hugging Face token for datastore authentication. It can be empty if not required.") so the documentation reads clearly and follows guidelines; edit the `hf_token` row in the table to replace "Can be empty if not required." with a full sentence referencing `hf_token`.docs/source/components/agents/tool-calling-agent/tool-calling-agent.md-22-22 (1)
22-22:⚠️ Potential issue | 🟡 MinorHyphenate “tool-calling” for consistency.
Use “tool-calling agent” in this sentence to match compound-adjective usage and improve readability.
Suggested edit
-The tool calling agent requires the `nvidia-nat[langchain]` plugin, which can be installed with one of the following commands, depending on whether you installed the NeMo Agent Toolkit from source or from a package. +The tool-calling agent requires the `nvidia-nat[langchain]` plugin, which can be installed with one of the following commands, depending on whether you installed the NeMo Agent Toolkit from source or from a package.As per coding guidelines, documentation must be clear and comprehensive and free of language-quality issues.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/source/components/agents/tool-calling-agent/tool-calling-agent.md` at line 22, Update the sentence that currently reads "The tool calling agent requires the `nvidia-nat[langchain]` plugin..." to hyphenate the compound adjective: change "tool calling agent" to "tool-calling agent" so it reads "The tool-calling agent requires the `nvidia-nat[langchain]` plugin..."; locate and edit the exact phrase "The tool calling agent requires the `nvidia-nat[langchain]` plugin" in the document to apply this change.docs/source/reference/rest-api/api-server-endpoints.md-31-31 (1)
31-31:⚠️ Potential issue | 🟡 MinorStandardize “Human-in-the-Loop” capitalization for consistency.
Line 31 uses “Human-in-the-loop” while the same concept is written elsewhere as “Human-in-the-Loop”. Please keep one canonical form across the page.
Suggested wording fix
-Versioned paths are currently experimental due to the added support of HTTP Human-in-the-loop (HITL) and OAuth. They are 1:1 compatible with the legacy endpoints for workflows not relying on those behaviors. +Versioned paths are currently experimental due to added support for HTTP Human-in-the-Loop (HITL) and OAuth. They are 1:1 compatible with the legacy endpoints for workflows that do not rely on those behaviors.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/source/reference/rest-api/api-server-endpoints.md` at line 31, Update the capitalization of the phrase "Human-in-the-loop" to the canonical "Human-in-the-Loop" across this document; locate the instance in the sentence "Versioned paths are currently experimental due to the added support of HTTP Human-in-the-loop (HITL) and OAuth." and change "Human-in-the-loop" to "Human-in-the-Loop" so it matches other occurrences on the page (search for the lowercase variant and replace with the canonical form).docs/source/run-workflows/observe/observe-workflow-with-catalyst.md-45-45 (1)
45-45:⚠️ Potential issue | 🟡 MinorFix typo in step title: “RagAI” → “RagaAI”.
The heading appears to miss an “a” and is inconsistent with the package/link naming used in this doc.
Suggested fix
-## Step 5: Install the RagAI Subpackage +## Step 5: Install the RagaAI SubpackageAs per coding guidelines, documentation must be clear and comprehensive and free of spelling mistakes.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/source/run-workflows/observe/observe-workflow-with-catalyst.md` at line 45, Update the Step 5 heading and any matching references so the subpackage name is spelled "RagaAI" instead of "RagAI": change the heading text "Step 5: Install the RagAI Subpackage" to "Step 5: Install the RagaAI Subpackage" and search for any occurrences of "RagAI" in the same section (including link text, package names, and anchors) and correct them to "RagaAI" to keep naming consistent.docs/source/build-workflows/embedders.md-99-100 (1)
99-100:⚠️ Potential issue | 🟡 MinorTighten wording: “remote embedding” → “remote embeddings.”
Use plural for clarity and grammatical correctness in the option description.
✏️ Suggested doc wording
-* `endpoint_url` - Endpoint URL for TEI server or Hugging Face Inference Endpoint. When set, uses remote embedding +* `endpoint_url` - Endpoint URL for TEI server or Hugging Face Inference Endpoint. When set, uses remote embeddingsAs per coding guidelines, "Documentation must be clear and comprehensive; ... ensure free of spelling mistakes."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/source/build-workflows/embedders.md` around lines 99 - 100, Update the option description that currently reads "remote embedding" to use the plural "remote embeddings" for clarity; specifically change the text associated with the `endpoint_url` option (which mentions TEI server or Hugging Face Inference Endpoint) to say it "uses remote embeddings" and verify any related mention near `api_key` remains grammatically consistent.docs/source/build-workflows/llms/index.md-173-177 (1)
173-177:⚠️ Potential issue | 🟡 MinorAdd a language tag to the fenced code block to satisfy markdown lint.
Line 175 uses an untyped fence, which triggers MD040.
🛠️ Suggested fix
-``` +```bash pip install "transformers[torch,accelerate]~=4.57"</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against the current code and only fix it if needed.
In
@docs/source/build-workflows/llms/index.mdaround lines 173 - 177, Add a
language tag to the fenced code block containing the pip command to satisfy
MD040; locate the fenced block that contains pip install
"transformers[torch,accelerate]~=4.57" inside the note and change the opening
fence to include the bash tag (e.g., ```bash) so the block is recognized as a
shell snippet.</details> </blockquote></details> <details> <summary>docs/source/run-workflows/observe/observe-workflow-with-otel-collector.md-72-72 (1)</summary><blockquote> `72-72`: _⚠️ Potential issue_ | _🟡 Minor_ **Fix the logical inconsistency and reduce redundancy.** The sentence starts with "If you installed the NeMo Agent Toolkit from source" but then says "depending on whether you installed the NeMo Agent Toolkit from source or from a package," which is contradictory. Additionally, repeating "NeMo Agent Toolkit" twice makes the sentence unnecessarily verbose. <details> <summary>📝 Proposed fix to improve clarity</summary> ```diff -If you installed the NeMo Agent Toolkit from source, you can install package extras with one of the following commands, depending on whether you installed the NeMo Agent Toolkit from source or from a package. +You can install package extras with one of the following commands, depending on whether you installed the NeMo Agent Toolkit from source or from a package. ``` Or, for better readability: ```diff -If you installed the NeMo Agent Toolkit from source, you can install package extras with one of the following commands, depending on whether you installed the NeMo Agent Toolkit from source or from a package. +Install package extras using one of the following commands, depending on whether you installed the NeMo Agent Toolkit from source or as a package. ``` </details> <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@docs/source/run-workflows/observe/observe-workflow-with-otel-collector.md` at line 72, The sentence beginning "If you installed the NeMo Agent Toolkit from source, you can install package extras with one of the following commands, depending on whether you installed the NeMo Agent Toolkit from source or from a package." is contradictory and redundant; replace it with a clear, concise sentence that either (a) addresses only the source-install case (e.g., "If you installed the NeMo Agent Toolkit from source, install package extras with:") or (b) presents two branches without repeating the product name (e.g., "If you installed from source, use X; if you installed from a package, use Y."), removing the duplicate "NeMo Agent Toolkit" phrasing and keeping the intended commands immediately after. ``` </details> </blockquote></details> <details> <summary>examples/agents/auto_memory_wrapper/configs/config_mem0.yml-61-61 (1)</summary><blockquote> `61-61`: _⚠️ Potential issue_ | _🟡 Minor_ **Add trailing newline at end of file.** Per coding guidelines, every file should end with a single newline character. <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@examples/agents/auto_memory_wrapper/configs/config_mem0.yml` at line 61, The file ending with the YAML scalar description "A ReAct agent with automatic Mem0 memory" is missing a trailing newline; update the file so it ends with a single newline character (add one blank line/linefeed at EOF) to comply with the coding guideline requiring every file to terminate with a newline. ``` </details> </blockquote></details> <details> <summary>docs/source/run-workflows/observe/observe.md-33-33 (1)</summary><blockquote> `33-33`: _⚠️ Potential issue_ | _🟡 Minor_ **Fix contradictory installation wording.** Line 33 says “already installed … from source” but then branches on source *or* package installs. Please rewrite to a neutral lead-in (for either install path) to avoid confusion. As per coding guidelines, documentation must be clear and comprehensive. <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@docs/source/run-workflows/observe/observe.md` at line 33, The sentence starting "If you have already installed the NeMo Agent Toolkit from source, you can install package extras..." is contradictory; replace it with a neutral lead-in that works for both install methods (source or package), e.g. "To install package extras for the NeMo Agent Toolkit (whether you installed from source or from a package), run the appropriate command below." Update the paragraph containing that sentence so it no longer assumes a source install and clearly signals the subsequent branch options for source vs package installs. ``` </details> </blockquote></details> <details> <summary>docs/source/build-workflows/llms/using-local-llms.md-74-75 (1)</summary><blockquote> `74-75`: _⚠️ Potential issue_ | _🟡 Minor_ **Remove `--runtime=nvidia` flag; it is unnecessary and legacy on modern Docker + NVIDIA Container Toolkit setups.** The `--runtime=nvidia` flag at lines 74 and 89 is not required when using `--gpus`. Modern NVIDIA documentation recommends using `--gpus` alone (e.g., `--gpus '"device=0"'`) without the runtime flag, as the NVIDIA Container Toolkit handles GPU integration automatically. The `--runtime=nvidia` flag is a legacy approach that can cause portability issues if users' Docker daemons are not explicitly configured to recognize the `nvidia` runtime, leading to command failures during copy-paste. Update both commands to remove `--runtime=nvidia` and rely on `--gpus` for GPU specification. <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@docs/source/build-workflows/llms/using-local-llms.md` around lines 74 - 75, Remove the legacy --runtime=nvidia flag from the Docker run examples and rely solely on the --gpus option; specifically, delete occurrences of "--runtime=nvidia" and keep the GPU spec as --gpus '"device=0"' in both command blocks (the lines showing --runtime=nvidia and --gpus) so the examples use the modern NVIDIA Container Toolkit approach. ``` </details> </blockquote></details> <details> <summary>docs/source/improve-workflows/evaluate.md-600-602 (1)</summary><blockquote> `600-602`: _⚠️ Potential issue_ | _🟡 Minor_ **Fix subject-verb agreement.** The compound subject "The input and the workflow output" requires the plural verb "go" rather than the singular "goes". <details> <summary>📝 Proposed fix</summary> ```diff -For unstructured entries, the entire dictionary is the input to the workflow -but the libraries don't know the individual columns. The input and the workflow output -goes through evaluation, where custom evaluators can handle +For unstructured entries, the entire dictionary is the input to the workflow +but the libraries don't know the individual columns. The input and the workflow output +go through evaluation, where custom evaluators can handle ``` </details> <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@docs/source/improve-workflows/evaluate.md` around lines 600 - 602, Fix the subject-verb agreement in the sentence containing "The input and the workflow output goes through evaluation" by changing "goes" to the plural verb "go" so it reads "The input and the workflow output go through evaluation"; locate and update that exact sentence in the evaluate.md content. ``` </details> </blockquote></details> <details> <summary>ci/scripts/run_tests.py-39-40 (1)</summary><blockquote> `39-40`: _⚠️ Potential issue_ | _🟡 Minor_ **Prefer non-exception control flow for `exitfirst` (Ruff TRY301/TRY003).** Line 270 raises and immediately catches a custom exception in the same scope. A boolean stop flag is simpler and removes the current lint warnings. <details> <summary>💡 Proposed fix</summary> ```diff -class TestFailure(Exception): - pass @@ - try: + stop_on_first_failure = False + try: for fut in as_completed(futs): if fut.result() != 0: failures += 1 if exitfirst: - raise TestFailure("Exiting on first failure as requested.") - - except TestFailure: - print("Cancelling remaining tests...") - shutdown_executor(None, None, wait=True) + stop_on_first_failure = True + break finally: + if stop_on_first_failure: + print("Cancelling remaining tests...") + shutdown_executor(None, None, wait=True) ex = None ``` </details> As per coding guidelines, "Use ruff (via 'ruff check --fix') for linting ... fix warnings unless explicitly ignored in pyproject.toml." Also applies to: 266-274 <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@ci/scripts/run_tests.py` around lines 39 - 40, Replace the custom exception-based control flow (the TestFailure class and the raise/catch of TestFailure used for exitfirst) with a simple boolean flag: remove the TestFailure class and where the code currently raises TestFailure (and immediately catches it) change to set a local stop_on_first_failure = True (or similar) and break/return from the loop or function as appropriate; update the catch block that currently handles TestFailure to instead check the flag or handle the normal control flow path. Look for the symbols TestFailure and the raise/catch pair around the exitfirst logic and convert them to a boolean stop flag and a clean loop break/return to eliminate the exception-based flow. ``` </details> </blockquote></details> <details> <summary>ci/scripts/run_tests.py-245-245 (1)</summary><blockquote> `245-245`: _⚠️ Potential issue_ | _🟡 Minor_ **Add missing parameter type hints for `shutdown_executor`.** Line 245 introduces untyped parameters (`_signum`, `_frame`), which violates the repository’s Python typing rule. <details> <summary>💡 Proposed fix</summary> ```diff from pathlib import Path +from types import FrameType @@ - def shutdown_executor(_signum, _frame, wait: bool = False): + def shutdown_executor(_signum: int | None, _frame: FrameType | None, wait: bool = False): ``` </details> As per coding guidelines, "Python methods should use type hints for all parameters and return values." <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@ci/scripts/run_tests.py` at line 245, The shutdown_executor function has untyped parameters _signum and _frame; update its signature to include parameter type hints and a return type (e.g., _signum: int, _frame: Optional[FrameType]) and -> None, and add the necessary imports (Optional from typing and FrameType from types) so the handler matches the repo typing rules while keeping the existing wait: bool = False parameter. ``` </details> </blockquote></details> <details> <summary>docs/source/improve-workflows/profiler.md-75-76 (1)</summary><blockquote> `75-76`: _⚠️ Potential issue_ | _🟡 Minor_ **Fix hyphenation in “scikit-learn-style models.”** Line 75 should hyphenate the compound modifier for grammar/lint consistency. <details> <summary>✍️ Proposed edit</summary> ```diff -- Under `packages/nvidia_nat_profiler/src/nat/plugins/profiler/forecasting`, the code trains scikit-learn style models on the usage data. +- Under `packages/nvidia_nat_profiler/src/nat/plugins/profiler/forecasting`, the code trains scikit-learn-style models on the usage data. ``` </details> As per coding guidelines: "Verify that documentation and comments are clear and comprehensive... free of spelling mistakes." <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@docs/source/improve-workflows/profiler.md` around lines 75 - 76, Update the sentence in the docs referencing packages/nvidia_nat_profiler/src/nat/plugins/profiler/forecasting to use the hyphenated compound modifier "scikit-learn-style models" (e.g., in the line mentioning model_trainer.py and its ability to train a LinearModel or a RandomForestModel on the aggregated usage data), replacing the un-hyphenated phrase to conform to grammar and lint rules. ``` </details> </blockquote></details> <details> <summary>ci/scripts/gitlab/report_test_results.py-274-276 (1)</summary><blockquote> `274-276`: _⚠️ Potential issue_ | _🟡 Minor_ **Use specific exception type and capture full stack trace in exception handler.** Line 274 catches a blind `Exception` (ruff BLE001 violation). Since the exception is caught and logged without re-raising, line 276 should use `logger.exception(msg)` instead of `logger.error(msg)` to preserve the full stack trace. Narrow the exception type to the specific exceptions that can be raised by the called functions. <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@ci/scripts/gitlab/report_test_results.py` around lines 274 - 276, Replace the blind "except Exception as e:" handler around the report parsing with specific exception types that the parsing/code can raise (e.g., json.JSONDecodeError, ValueError, KeyError — adjust to the actual functions used) and change the logging call from logger.error(msg) to logger.exception(msg) so the full stack trace is captured; keep the same msg variable and only fall back to a broader Exception catch if absolutely necessary but still use logger.exception there. ``` </details> </blockquote></details> </blockquote></details> <details> <summary>🧹 Nitpick comments (7)</summary><blockquote> <details> <summary>docs/source/run-workflows/observe/observe-workflow-with-langsmith.md (1)</summary><blockquote> `37-37`: **Normalize heading hierarchy for readability and navigation.** Lines 37, 45, 62, and 78 are now `##` while Line 26 is still `### Prerequisites`, which creates an inconsistent H1 → H3 → H2 structure. Please keep section levels monotonic (for example, make “Prerequisites” `##` or keep steps at `###`). As per coding guidelines, documentation must be clear and comprehensive; consistent heading structure improves clarity and navigation. Also applies to: 45-45, 62-62, 78-78 <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@docs/source/run-workflows/observe/observe-workflow-with-langsmith.md` at line 37, The document has inconsistent heading levels: "Prerequisites" is a level-3 (###) while the steps ("Step 1: Install the LangSmith Subpackage", and other headings at lines referenced) are level-2 (##); update the headings so the hierarchy is monotonic—either promote "Prerequisites" to `## Prerequisites` to match the steps, or demote all step headings to `###`—and apply the same change to the other step headings ("Step 1: Install the LangSmith Subpackage", the headings at lines 45, 62, and 78) so all section levels are consistent for proper navigation. ``` </details> </blockquote></details> <details> <summary>docs/source/reference/rest-api/api-server-endpoints.md (1)</summary><blockquote> `440-440`: **Minor wording polish: add article for readability.** Consider “on **the** OpenAI Chat Completions endpoint” for smoother phrasing in the table description. <details> <summary>Suggested wording tweak</summary> ```diff -| `enable_interactive_extensions` | boolean | `false` | Enable [HTTP interactive execution](./http-interactive-execution.md) on OpenAI Chat Completions endpoint | +| `enable_interactive_extensions` | boolean | `false` | Enable [HTTP interactive execution](./http-interactive-execution.md) on the OpenAI Chat Completions endpoint | ``` </details> <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@docs/source/reference/rest-api/api-server-endpoints.md` at line 440, Minor wording polish: update the table description for the `enable_interactive_extensions` entry to read "Enable HTTP interactive execution on the OpenAI Chat Completions endpoint" by inserting the article "the" before "OpenAI" in the string associated with `enable_interactive_extensions` to improve readability. ``` </details> </blockquote></details> <details> <summary>docs/source/conf.py (1)</summary><blockquote> `618-622`: **Consider adding type hints to the `setup` function.** Per coding guidelines, Python methods should use type hints for all parameters and return values. The Sphinx setup function has a well-defined signature. <details> <summary>🔧 Suggested type hints</summary> ```diff - def setup(sphinx): + def setup(sphinx: "sphinx.application.Sphinx") -> None: ``` You may also need to add an import under the `TYPE_CHECKING` block: ```python if typing.TYPE_CHECKING: import sphinx.application from autoapi._objects import PythonObject ``` </details> <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@docs/source/conf.py` around lines 618 - 622, Annotate the Sphinx setup function with proper type hints: give the parameter a Sphinx application type (e.g. app: "sphinx.application.Sphinx") and the return type (e.g. -> dict[str, object] | None) and update the function signature for setup to use those annotations; add the suggested TYPE_CHECKING imports (import typing; if typing.TYPE_CHECKING: import sphinx.application and, if needed, autoapi._objects.PythonObject) so the annotations resolve without runtime imports, and ensure references to skip_pydantic_special_attrs and clean_markdown_from_docstrings remain unchanged. ``` </details> </blockquote></details> <details> <summary>examples/agents/tests/conftest.py (1)</summary><blockquote> `66-77`: **Add return type hint to `_build_nat_client`.** Per coding guidelines, Python methods should use type hints for all parameters and return values. The async generator should have a return type hint. <details> <summary>💡 Suggested type hint addition</summary> ```diff +from collections.abc import AsyncIterator +from httpx import AsyncClient + -async def _build_nat_client(config_path: Path): +async def _build_nat_client(config_path: Path) -> AsyncIterator[AsyncClient]: config = load_config(config_path) ``` Note: The exact return type depends on what `build_nat_client` yields. Adjust the type accordingly. </details> <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@examples/agents/tests/conftest.py` around lines 66 - 77, The async generator _build_nat_client lacks a return type hint; annotate it to return an AsyncGenerator of the client type (e.g., AsyncGenerator[NatClientType, None]) and import AsyncGenerator from typing (or typing_extensions if needed). Use the actual client type returned by build_nat_client for NatClientType (or a more specific protocol/class) and update the signature def _build_nat_client(config_path: Path) -> AsyncGenerator[NatClientType, None]: accordingly, ensuring imports are added/updated. ``` </details> </blockquote></details> <details> <summary>examples/MCP/simple_calculator_mcp/README.md (1)</summary><blockquote> `110-110`: **Clarify timezone behavior to avoid contradicting the required tool flow.** Line 110 says timezone is "always assumed", but the new contract requires reading timezone from `current_timezone` and passing that value to `get_current_time`. Please reword to avoid implying hardcoded assumption. <details> <summary>📝 Suggested doc wording</summary> ```diff -- `mcp_time`: Connects to a local MCP server using stdio transport to get current date and time. The timezone is always assumed to be America/Los_Angeles +- `mcp_time`: Connects to a local MCP server using stdio transport to get current date and time. The workflow first calls `current_timezone` and passes that returned value to `get_current_time` (in this example setup, it resolves to `America/Los_Angeles`). ``` </details> <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@examples/MCP/simple_calculator_mcp/README.md` at line 110, The README line currently states the timezone is "always assumed to be America/Los_Angeles", which contradicts the new contract; update the description of mcp_time to say that the mcp_time tool connects to a local MCP server using stdio transport to retrieve the current date and time and that it reads the timezone from current_timezone and passes that value to get_current_time (instead of hardcoding America/Los_Angeles). ``` </details> </blockquote></details> <details> <summary>examples/advanced_agents/alert_triage_agent/tests/test_alert_triage_agent_workflow.py (1)</summary><blockquote> `59-62`: **Consider replacing the hard length threshold with structure-based assertions.** `len(result) > 200` is brittle for integration output and can create avoidable flakiness. Prefer checking for expected sections/signals in the triage report format instead of a fixed character count. As per coding guidelines, tests should be comprehensive and cover edge cases. <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@examples/advanced_agents/alert_triage_agent/tests/test_alert_triage_agent_workflow.py` around lines 59 - 62, Replace the brittle length check on the test variable result in test_alert_triage_agent_workflow.py with structure-based assertions: instead of assert len(result) > 200, assert that result contains expected report sections or markers (e.g., "Summary", "Severity", "Recommended Actions", "Evidence", or other domain-specific headings) or parse result as structured output (JSON/YAML) and assert required keys exist; update the test to check for multiple distinct section substrings and non-empty content for each (e.g., verify "Summary" in result and that the substring after "Summary" is non-empty) to make the assertion robust and less flaky. ``` </details> </blockquote></details> <details> <summary>ci/scripts/model_health_check.py (1)</summary><blockquote> `126-167`: **Prefer `httpx` for outbound HTTP calls in this script.** The request paths in `_nim_get_models` and `_nim_post` currently use `urllib.request`. Per project guidelines, `httpx` is preferred with SSL verification enabled by default and clearer timeout/error handling. This would align with OWASP recommendations and improve consistency across the codebase. <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@ci/scripts/model_health_check.py` around lines 126 - 167, Replace urllib usage in _nim_get_models and _nim_post with httpx to standardize outbound HTTP calls; for _nim_get_models use httpx.Client or httpx.request to GET f"{NIM_API_BASE}/models" with timeout=REQUEST_TIMEOUT and default SSL verification, parse resp.json() and return the set comprehension {m["id"] ...} on success, and on exceptions (httpx.HTTPStatusError, httpx.RequestError, json.JSONDecodeError) log the warning and return set(); for _nim_post send a POST to f"{NIM_API_BASE}/{endpoint}" with json=payload (or bytes decoded) and timeout=REQUEST_TIMEOUT, catch httpx.HTTPStatusError to extract response JSON "detail" if present and return (status_code, detail), and catch httpx.RequestError to return (0, f"Connection error: {e}"); preserve function signatures (_nim_get_models/_nim_post), keep Authorization header "Bearer {api_key}", and ensure SSL verification remains enabled by not disabling it. ``` </details> </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary>Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.gitlab-ci.yml:
- Line 63: The CI variable NAT_CI_PROXIED_OPENAI_BASE_URL is being assigned to
itself which creates a self-referential cycle; remove this assignment and either
(a) set a concrete default value here, (b) remove the line so the job reads the
value from project/group CI variables without reassigning, or (c) if it must be
optional, implement fallback logic in the job script (e.g., read
$NAT_CI_PROXIED_OPENAI_BASE_URL and substitute a default) so the pipeline does
not rely on a self-referential declaration.In
@ci/scripts/gitlab/report_test_results.py:
- Around line 218-234: The two places that append divider dicts to
failure_blocks (the first failure_blocks.append({"type": "divider"}) and the one
before adding the job_url divider) must also append corresponding empty entries
to failure_text so the two lists remain length-aligned before chunking/zip;
update the code paths that call failure_blocks.append({"type":"divider"}) (and
any other places that append blocks without text) to call
failure_text.append("") right after, ensuring add_text, failure_blocks and
failure_text remain in sync before the BLOCK_LIMIT-based chunking and subsequent
zip.In
@ci/scripts/model_health_check.py:
- Around line 51-52: Replace the broad "except Exception:" used around the call
to GitWrapper.get_repo_dir() with a narrow exception tuple that matches the
actual failures from that call (e.g., except (ImportError, ModuleNotFoundError,
AttributeError): or include OSError if filesystem/git operations may raise it);
update the handler to only set _FALLBACK_REPO when one of those specific
exceptions occurs and optionally log the caught exception for visibility so
unrelated errors don't silently fall through to the hardcoded fallback.In
@docs/source/get-started/installation.md:
- Line 53: Remove the nonexistent "nat red-team" command reference: locate the
line containing the package variantsnvidia-nat[security]and
nvidia-nat-securityand delete or replace the parenthetical "nat red-team"
text; instead describe the package as providing security/red-team-related
components (e.g., "Security and red-team components") or remove the
parenthetical entirely so the line reads onlynvidia-nat[security]or
nvidia-nat-securitywithout referencingnat red-team.In
@docs/source/run-workflows/observe/observe.md:
- Around line 188-189: Update the Sphinx roles for the module references:
replace the{py:class}roles used for nat.plugins.profiler.decorators and
nat.plugins.profiler.callbacks with the{py:mod}role so the references are
correctly treated as modules (change the two occurrences in the observe.md
snippet).In
@examples/advanced_agents/alert_triage_agent/src/nat_alert_triage_agent/register.py:
- Around line 139-149: The current extraction treats
output["messages"][-1].content (raw_result) as a string and discards any
non-string structured content; instead, detect if raw_result is a list
(structured LangChain message content) and reconstruct a string by iterating the
list: for each block, if it's a string append it, if it's a dict extract likely
text fields such as "text", "content", or nested "content" strings (fall back to
JSON-stringifying unknown dicts) and join them with spaces, then strip into
result; keep the existing fallback warning and error message if the
reconstructed result is still empty. Ensure you update the logic around
raw_result/result so it handles both str and list content cases from
agent_executor.ainvoke() / output["messages"][-1].content.
Outside diff comments:
In @.pre-commit-config.yaml:
- Around line 33-62: Add a new uv-lock hook entry for the MemMachine package to
the per-package hooks block: create a line similar to the other entries using
id: uv-lock, name: "uv-lock-memmachine", args: [--project,
packages/nvidia_nat_memmachine], files:
"packages/nvidia_nat_memmachine/pyproject.toml" so that the uv-lock hook (like
"uv-lock-mem0ai"/"uv-lock-core") enforces the lockfile for
packages/nvidia_nat_memmachine.In
@docs/source/improve-workflows/evaluate.md:
- Line 22: Update all occurrences of the lowercase phrase "the toolkit" to "the
Toolkit" in this document; specifically change the sentence that follows "NeMo
Agent Toolkit provides a set of evaluators..." so it reads "...the Toolkit
provides a plugin system to add custom evaluators." Search for any other
instances of "toolkit" in this file and capitalize them to "Toolkit" to match
the new style guideline.In
@docs/source/run-workflows/observe/observe-workflow-with-weave.md:
- Line 18: The page title "# Observing a Workflow with W&B Weave" does not
follow the required product-name format; update the Markdown title to include
"NVIDIA NeMo Agent Toolkit" (for example, change the header to include "NVIDIA
NeMo Agent Toolkit — Observing a Workflow with W&B Weave" or similar) so the
document title complies with the docs/source/**/*.md naming guideline; modify
the title line in this file accordingly.
Minor comments:
In@ci/scripts/gitlab/report_test_results.py:
- Around line 274-276: Replace the blind "except Exception as e:" handler around
the report parsing with specific exception types that the parsing/code can raise
(e.g., json.JSONDecodeError, ValueError, KeyError — adjust to the actual
functions used) and change the logging call from logger.error(msg) to
logger.exception(msg) so the full stack trace is captured; keep the same msg
variable and only fall back to a broader Exception catch if absolutely necessary
but still use logger.exception there.In
@ci/scripts/run_tests.py:
- Around line 39-40: Replace the custom exception-based control flow (the
TestFailure class and the raise/catch of TestFailure used for exitfirst) with a
simple boolean flag: remove the TestFailure class and where the code currently
raises TestFailure (and immediately catches it) change to set a local
stop_on_first_failure = True (or similar) and break/return from the loop or
function as appropriate; update the catch block that currently handles
TestFailure to instead check the flag or handle the normal control flow path.
Look for the symbols TestFailure and the raise/catch pair around the exitfirst
logic and convert them to a boolean stop flag and a clean loop break/return to
eliminate the exception-based flow.- Line 245: The shutdown_executor function has untyped parameters _signum and
_frame; update its signature to include parameter type hints and a return type
(e.g., _signum: int, _frame: Optional[FrameType]) and -> None, and add the
necessary imports (Optional from typing and FrameType from types) so the handler
matches the repo typing rules while keeping the existing wait: bool = False
parameter.In
@docs/source/build-workflows/embedders.md:
- Around line 99-100: Update the option description that currently reads "remote
embedding" to use the plural "remote embeddings" for clarity; specifically
change the text associated with theendpoint_urloption (which mentions TEI
server or Hugging Face Inference Endpoint) to say it "uses remote embeddings"
and verify any related mention nearapi_keyremains grammatically consistent.In
@docs/source/build-workflows/llms/index.md:
- Around line 173-177: Add a language tag to the fenced code block containing
the pip command to satisfy MD040; locate the fenced block that contains pip
install "transformers[torch,accelerate]~=4.57" inside the note and change the
opening fence to include the bash tag (e.g., ```bash) so the block is recognized
as a shell snippet.In
@docs/source/build-workflows/llms/using-local-llms.md:
- Around line 74-75: Remove the legacy --runtime=nvidia flag from the Docker run
examples and rely solely on the --gpus option; specifically, delete occurrences
of "--runtime=nvidia" and keep the GPU spec as --gpus '"device=0"' in both
command blocks (the lines showing --runtime=nvidia and --gpus) so the examples
use the modern NVIDIA Container Toolkit approach.In
@docs/source/components/agents/tool-calling-agent/tool-calling-agent.md:
- Line 22: Update the sentence that currently reads "The tool calling agent
requires thenvidia-nat[langchain]plugin..." to hyphenate the compound
adjective: change "tool calling agent" to "tool-calling agent" so it reads "The
tool-calling agent requires thenvidia-nat[langchain]plugin..."; locate and
edit the exact phrase "The tool calling agent requires the
nvidia-nat[langchain]plugin" in the document to apply this change.In
@docs/source/improve-workflows/evaluate.md:
- Around line 600-602: Fix the subject-verb agreement in the sentence containing
"The input and the workflow output goes through evaluation" by changing "goes"
to the plural verb "go" so it reads "The input and the workflow output go
through evaluation"; locate and update that exact sentence in the evaluate.md
content.In
@docs/source/improve-workflows/finetuning/dpo_with_nemo_customizer.md:
- Line 383: The table entry for hf_token contains a sentence fragment; update
the description forhf_tokento a full sentence (for example: "Hugging Face
token for datastore authentication. It can be empty if not required.") so the
documentation reads clearly and follows guidelines; edit thehf_tokenrow in
the table to replace "Can be empty if not required." with a full sentence
referencinghf_token.In
@docs/source/improve-workflows/profiler.md:
- Around line 75-76: Update the sentence in the docs referencing
packages/nvidia_nat_profiler/src/nat/plugins/profiler/forecasting to use the
hyphenated compound modifier "scikit-learn-style models" (e.g., in the line
mentioning model_trainer.py and its ability to train a LinearModel or a
RandomForestModel on the aggregated usage data), replacing the un-hyphenated
phrase to conform to grammar and lint rules.In
@docs/source/reference/rest-api/api-server-endpoints.md:
- Line 31: Update the capitalization of the phrase "Human-in-the-loop" to the
canonical "Human-in-the-Loop" across this document; locate the instance in the
sentence "Versioned paths are currently experimental due to the added support of
HTTP Human-in-the-loop (HITL) and OAuth." and change "Human-in-the-loop" to
"Human-in-the-Loop" so it matches other occurrences on the page (search for the
lowercase variant and replace with the canonical form).In
@docs/source/run-workflows/observe/observe-workflow-with-catalyst.md:
- Line 45: Update the Step 5 heading and any matching references so the
subpackage name is spelled "RagaAI" instead of "RagAI": change the heading text
"Step 5: Install the RagAI Subpackage" to "Step 5: Install the RagaAI
Subpackage" and search for any occurrences of "RagAI" in the same section
(including link text, package names, and anchors) and correct them to "RagaAI"
to keep naming consistent.In
@docs/source/run-workflows/observe/observe-workflow-with-otel-collector.md:
- Line 72: The sentence beginning "If you installed the NeMo Agent Toolkit from
source, you can install package extras with one of the following commands,
depending on whether you installed the NeMo Agent Toolkit from source or from a
package." is contradictory and redundant; replace it with a clear, concise
sentence that either (a) addresses only the source-install case (e.g., "If you
installed the NeMo Agent Toolkit from source, install package extras with:") or
(b) presents two branches without repeating the product name (e.g., "If you
installed from source, use X; if you installed from a package, use Y."),
removing the duplicate "NeMo Agent Toolkit" phrasing and keeping the intended
commands immediately after.In
@docs/source/run-workflows/observe/observe.md:
- Line 33: The sentence starting "If you have already installed the NeMo Agent
Toolkit from source, you can install package extras..." is contradictory;
replace it with a neutral lead-in that works for both install methods (source or
package), e.g. "To install package extras for the NeMo Agent Toolkit (whether
you installed from source or from a package), run the appropriate command
below." Update the paragraph containing that sentence so it no longer assumes a
source install and clearly signals the subsequent branch options for source vs
package installs.In
@examples/agents/auto_memory_wrapper/configs/config_mem0.yml:
- Line 61: The file ending with the YAML scalar description "A ReAct agent with
automatic Mem0 memory" is missing a trailing newline; update the file so it ends
with a single newline character (add one blank line/linefeed at EOF) to comply
with the coding guideline requiring every file to terminate with a newline.
Nitpick comments:
In@ci/scripts/model_health_check.py:
- Around line 126-167: Replace urllib usage in _nim_get_models and _nim_post
with httpx to standardize outbound HTTP calls; for _nim_get_models use
httpx.Client or httpx.request to GET f"{NIM_API_BASE}/models" with
timeout=REQUEST_TIMEOUT and default SSL verification, parse resp.json() and
return the set comprehension {m["id"] ...} on success, and on exceptions
(httpx.HTTPStatusError, httpx.RequestError, json.JSONDecodeError) log the
warning and return set(); for _nim_post send a POST to
f"{NIM_API_BASE}/{endpoint}" with json=payload (or bytes decoded) and
timeout=REQUEST_TIMEOUT, catch httpx.HTTPStatusError to extract response JSON
"detail" if present and return (status_code, detail), and catch
httpx.RequestError to return (0, f"Connection error: {e}"); preserve function
signatures (_nim_get_models/_nim_post), keep Authorization header "Bearer
{api_key}", and ensure SSL verification remains enabled by not disabling it.In
@docs/source/conf.py:
- Around line 618-622: Annotate the Sphinx setup function with proper type
hints: give the parameter a Sphinx application type (e.g. app:
"sphinx.application.Sphinx") and the return type (e.g. -> dict[str, object] |
None) and update the function signature for setup to use those annotations; add
the suggested TYPE_CHECKING imports (import typing; if typing.TYPE_CHECKING:
import sphinx.application and, if needed, autoapi._objects.PythonObject) so the
annotations resolve without runtime imports, and ensure references to
skip_pydantic_special_attrs and clean_markdown_from_docstrings remain unchanged.In
@docs/source/reference/rest-api/api-server-endpoints.md:
- Line 440: Minor wording polish: update the table description for the
enable_interactive_extensionsentry to read "Enable HTTP interactive execution
on the OpenAI Chat Completions endpoint" by inserting the article "the" before
"OpenAI" in the string associated withenable_interactive_extensionsto
improve readability.In
@docs/source/run-workflows/observe/observe-workflow-with-langsmith.md:
- Line 37: The document has inconsistent heading levels: "Prerequisites" is a
level-3 (###) while the steps ("Step 1: Install the LangSmith Subpackage", and
other headings at lines referenced) are level-2 (##); update the headings so the
hierarchy is monotonic—either promote "Prerequisites" to## Prerequisitesto
match the steps, or demote all step headings to###—and apply the same change
to the other step headings ("Step 1: Install the LangSmith Subpackage", the
headings at lines 45, 62, and 78) so all section levels are consistent for
proper navigation.In
@examples/advanced_agents/alert_triage_agent/tests/test_alert_triage_agent_workflow.py:
- Around line 59-62: Replace the brittle length check on the test variable
result in test_alert_triage_agent_workflow.py with structure-based assertions:
instead of assert len(result) > 200, assert that result contains expected report
sections or markers (e.g., "Summary", "Severity", "Recommended Actions",
"Evidence", or other domain-specific headings) or parse result as structured
output (JSON/YAML) and assert required keys exist; update the test to check for
multiple distinct section substrings and non-empty content for each (e.g.,
verify "Summary" in result and that the substring after "Summary" is non-empty)
to make the assertion robust and less flaky.In
@examples/agents/tests/conftest.py:
- Around line 66-77: The async generator _build_nat_client lacks a return type
hint; annotate it to return an AsyncGenerator of the client type (e.g.,
AsyncGenerator[NatClientType, None]) and import AsyncGenerator from typing (or
typing_extensions if needed). Use the actual client type returned by
build_nat_client for NatClientType (or a more specific protocol/class) and
update the signature def _build_nat_client(config_path: Path) ->
AsyncGenerator[NatClientType, None]: accordingly, ensuring imports are
added/updated.In
@examples/MCP/simple_calculator_mcp/README.md:
- Line 110: The README line currently states the timezone is "always assumed to
be America/Los_Angeles", which contradicts the new contract; update the
description of mcp_time to say that the mcp_time tool connects to a local MCP
server using stdio transport to retrieve the current date and time and that it
reads the timezone from current_timezone and passes that value to
get_current_time (instead of hardcoding America/Los_Angeles).</details> --- <details> <summary>ℹ️ Review info</summary> <details> <summary>⚙️ Run configuration</summary> **Configuration used**: Path: .coderabbit.yaml **Review profile**: CHILL **Plan**: Pro **Run ID**: `f36dc651-eddf-44bf-9b69-84ea5ee93d66` </details> <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 3b2e00506927839414eec475d89f07de297c122c and e76d8570710ceaadbbbecf2399711cd0437f3a3e. </details> <details> <summary>⛔ Files ignored due to path filters (24)</summary> * `examples/A2A/currency_agent_a2a/uv.lock` is excluded by `!**/*.lock` * `examples/A2A/math_assistant_a2a/uv.lock` is excluded by `!**/*.lock` * `examples/A2A/math_assistant_a2a_protected/uv.lock` is excluded by `!**/*.lock` * `examples/HITL/por_to_jiratickets/uv.lock` is excluded by `!**/*.lock` * `examples/HITL/simple_calculator_hitl/uv.lock` is excluded by `!**/*.lock` * `examples/MCP/kaggle_mcp/uv.lock` is excluded by `!**/*.lock` * `examples/MCP/service_account_auth_mcp/uv.lock` is excluded by `!**/*.lock` * `examples/MCP/simple_auth_mcp/uv.lock` is excluded by `!**/*.lock` * `examples/MCP/simple_calculator_fastmcp/uv.lock` is excluded by `!**/*.lock` * `examples/MCP/simple_calculator_fastmcp_protected/uv.lock` is excluded by `!**/*.lock` * `examples/MCP/simple_calculator_mcp/uv.lock` is excluded by `!**/*.lock` * `examples/MCP/simple_calculator_mcp_protected/uv.lock` is excluded by `!**/*.lock` * `examples/RAG/simple_rag/uv.lock` is excluded by `!**/*.lock` * `examples/advanced_agents/alert_triage_agent/uv.lock` is excluded by `!**/*.lock` * `examples/advanced_agents/profiler_agent/tests/test_spans.csv` is excluded by `!**/*.csv` * `examples/agents/uv.lock` is excluded by `!**/*.lock` * `examples/control_flow/hybrid_control_flow/uv.lock` is excluded by `!**/*.lock` * `examples/control_flow/parallel_executor/uv.lock` is excluded by `!**/*.lock` * `examples/control_flow/router_agent/uv.lock` is excluded by `!**/*.lock` * `examples/control_flow/sequential_executor/uv.lock` is excluded by `!**/*.lock` * `examples/custom_functions/automated_description_generation/uv.lock` is excluded by `!**/*.lock` * `examples/custom_functions/plot_charts/uv.lock` is excluded by `!**/*.lock` * `examples/documentation_guides/uv.lock` is excluded by `!**/*.lock` * `examples/documentation_guides/workflows/text_file_ingest/uv.lock` is excluded by `!**/*.lock` </details> <details> <summary>📒 Files selected for processing (111)</summary> * `.coderabbit.yaml` * `.gitlab-ci.yml` * `.pre-commit-config.yaml` * `.pytest.ini` * `CHANGELOG.md` * `README.md` * `ci/release/update-version.sh` * `ci/release/update_toml_dep.py` * `ci/scripts/github/build_wheel.sh` * `ci/scripts/gitlab/common.sh` * `ci/scripts/gitlab/model_health_check.sh` * `ci/scripts/gitlab/report_test_results.py` * `ci/scripts/gitlab/tests.sh` * `ci/scripts/model_health_check.py` * `ci/scripts/path_checks.py` * `ci/scripts/run_tests.py` * `ci/vale/styles/config/vocabularies/nat/accept.txt` * `conftest.py` * `docs/source/build-workflows/embedders.md` * `docs/source/build-workflows/llms/index.md` * `docs/source/build-workflows/llms/using-local-llms.md` * `docs/source/components/agents/index.md` * `docs/source/components/agents/parallel-executor/index.md` * `docs/source/components/agents/parallel-executor/parallel-executor.md` * `docs/source/components/agents/react-agent/react-agent.md` * `docs/source/components/agents/reasoning-agent/reasoning-agent.md` * `docs/source/components/agents/rewoo-agent/rewoo-agent.md` * `docs/source/components/agents/router-agent/router-agent.md` * `docs/source/components/agents/tool-calling-agent/tool-calling-agent.md` * `docs/source/components/auth/mcp-auth/index.md` * `docs/source/components/auth/mcp-auth/mcp-auth-token-storage.md` * `docs/source/components/functions/text-to-sql.md` * `docs/source/components/integrations/frameworks.md` * `docs/source/conf.py` * `docs/source/extend/testing/add-unit-tests-for-tools.md` * `docs/source/get-started/installation.md` * `docs/source/get-started/tutorials/add-tools-to-a-workflow.md` * `docs/source/get-started/tutorials/create-a-new-workflow.md` * `docs/source/improve-workflows/evaluate.md` * `docs/source/improve-workflows/finetuning/dpo_with_nemo_customizer.md` * `docs/source/improve-workflows/optimizer.md` * `docs/source/improve-workflows/profiler.md` * `docs/source/improve-workflows/sizing-calc.md` * `docs/source/reference/cli.md` * `docs/source/reference/rest-api/api-server-endpoints.md` * `docs/source/reference/rest-api/evaluate-api.md` * `docs/source/resources/migration-guide.md` * `docs/source/run-workflows/a2a-server.md` * `docs/source/run-workflows/observe/observe-workflow-with-catalyst.md` * `docs/source/run-workflows/observe/observe-workflow-with-data-flywheel.md` * `docs/source/run-workflows/observe/observe-workflow-with-dbnl.md` * `docs/source/run-workflows/observe/observe-workflow-with-dynatrace.md` * `docs/source/run-workflows/observe/observe-workflow-with-galileo.md` * `docs/source/run-workflows/observe/observe-workflow-with-langsmith.md` * `docs/source/run-workflows/observe/observe-workflow-with-otel-collector.md` * `docs/source/run-workflows/observe/observe-workflow-with-phoenix.md` * `docs/source/run-workflows/observe/observe-workflow-with-weave.md` * `docs/source/run-workflows/observe/observe.md` * `examples/MCP/kaggle_mcp/README.md` * `examples/MCP/simple_auth_mcp/configs/config-mcp-auth-jira-per-user.yml` * `examples/MCP/simple_calculator_mcp/README.md` * `examples/MCP/simple_calculator_mcp/configs/config-mcp-client.yml` * `examples/MCP/simple_calculator_mcp/configs/config-per-user-mcp-client.yml` * `examples/README.md` * `examples/advanced_agents/alert_triage_agent/pyproject.toml` * `examples/advanced_agents/alert_triage_agent/src/nat_alert_triage_agent/configs/config_offline_mode.yml` * `examples/advanced_agents/alert_triage_agent/src/nat_alert_triage_agent/register.py` * `examples/advanced_agents/alert_triage_agent/tests/test_alert_triage_agent_workflow.py` * `examples/advanced_agents/profiler_agent/README.md` * `examples/advanced_agents/profiler_agent/configs` * `examples/advanced_agents/profiler_agent/src/nat_profiler_agent/agent.py` * `examples/advanced_agents/profiler_agent/src/nat_profiler_agent/configs/config.yml` * `examples/advanced_agents/profiler_agent/src/nat_profiler_agent/data_models.py` * `examples/advanced_agents/profiler_agent/src/nat_profiler_agent/prompts.py` * `examples/advanced_agents/profiler_agent/src/nat_profiler_agent/register.py` * `examples/advanced_agents/profiler_agent/src/nat_profiler_agent/tool/flow_chart.py` * `examples/advanced_agents/profiler_agent/src/nat_profiler_agent/tool/px_query.py` * `examples/advanced_agents/profiler_agent/src/nat_profiler_agent/tool/response_composer.py` * `examples/advanced_agents/profiler_agent/src/nat_profiler_agent/tool/token_usage.py` * `examples/advanced_agents/profiler_agent/src/nat_profiler_agent/tool/utils.py` * `examples/advanced_agents/profiler_agent/tests/test_profiler_agent.py` * `examples/agents/auto_memory_wrapper/README.md` * `examples/agents/auto_memory_wrapper/configs/config_mem0.yml` * `examples/agents/auto_memory_wrapper/configs/config_zep.yml` * `examples/agents/mixture_of_agents/README.md` * `examples/agents/mixture_of_agents/configs/config.yml` * `examples/agents/pyproject.toml` * `examples/agents/react/README.md` * `examples/agents/tests/conftest.py` * `examples/agents/tests/test_agents.py` * `examples/agents/tool_calling/README.md` * `examples/agents/tool_calling/configs/config-reasoning.yml` * `examples/agents/tool_calling/configs/config-responses-api.yml` * `examples/control_flow/parallel_executor/README.md` * `examples/control_flow/parallel_executor/configs` * `examples/control_flow/parallel_executor/pyproject.toml` * `examples/control_flow/parallel_executor/src/nat_parallel_executor/__init__.py` * `examples/control_flow/parallel_executor/src/nat_parallel_executor/configs/config.yml` * `examples/control_flow/parallel_executor/tests/test_parallel_executor_example.py` * `examples/documentation_guides/locally_hosted_llms/nim_config.yml` * `examples/dynamo_integration/.env.example` * `examples/dynamo_integration/README.md` * `examples/dynamo_integration/latency_sensitivity_demo/INSTALL_LIBRARY.md` * `examples/dynamo_integration/latency_sensitivity_demo/README.md` * `examples/dynamo_integration/latency_sensitivity_demo/configs` * `examples/dynamo_integration/latency_sensitivity_demo/data` * `examples/dynamo_integration/latency_sensitivity_demo/pyproject.toml` * `examples/dynamo_integration/latency_sensitivity_demo/src/latency_sensitivity_demo/__init__.py` * `examples/dynamo_integration/latency_sensitivity_demo/src/latency_sensitivity_demo/compare_sensitivity_perf.py` * `examples/dynamo_integration/latency_sensitivity_demo/src/latency_sensitivity_demo/configs/config_profile.yml` * `examples/dynamo_integration/latency_sensitivity_demo/src/latency_sensitivity_demo/configs/config_with_trie.yml` </details> <details> <summary>💤 Files with no reviewable changes (18)</summary> * examples/agents/auto_memory_wrapper/configs/config_zep.yml * examples/advanced_agents/profiler_agent/src/nat_profiler_agent/prompts.py * ci/release/update-version.sh * examples/advanced_agents/profiler_agent/src/nat_profiler_agent/tool/utils.py * examples/advanced_agents/profiler_agent/src/nat_profiler_agent/configs/config.yml * examples/advanced_agents/profiler_agent/configs * examples/advanced_agents/profiler_agent/README.md * examples/advanced_agents/profiler_agent/src/nat_profiler_agent/data_models.py * examples/advanced_agents/profiler_agent/src/nat_profiler_agent/agent.py * examples/advanced_agents/profiler_agent/src/nat_profiler_agent/tool/token_usage.py * examples/advanced_agents/profiler_agent/src/nat_profiler_agent/tool/response_composer.py * examples/agents/tool_calling/configs/config-responses-api.yml * ci/release/update_toml_dep.py * examples/advanced_agents/profiler_agent/src/nat_profiler_agent/register.py * examples/advanced_agents/profiler_agent/tests/test_profiler_agent.py * examples/advanced_agents/profiler_agent/src/nat_profiler_agent/tool/px_query.py * ci/scripts/path_checks.py * examples/advanced_agents/profiler_agent/src/nat_profiler_agent/tool/flow_chart.py </details> <details> <summary>✅ Files skipped from review due to trivial changes (13)</summary> * docs/source/get-started/tutorials/create-a-new-workflow.md * docs/source/get-started/tutorials/add-tools-to-a-workflow.md * docs/source/components/integrations/frameworks.md * docs/source/components/agents/parallel-executor/parallel-executor.md * docs/source/components/agents/rewoo-agent/rewoo-agent.md * docs/source/components/functions/text-to-sql.md * docs/source/run-workflows/observe/observe-workflow-with-dbnl.md * docs/source/components/agents/router-agent/router-agent.md * docs/source/run-workflows/observe/observe-workflow-with-phoenix.md * examples/MCP/simple_auth_mcp/configs/config-mcp-auth-jira-per-user.yml * docs/source/run-workflows/observe/observe-workflow-with-dynatrace.md * docs/source/improve-workflows/optimizer.md * CHANGELOG.md </details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
examples/advanced_agents/alert_triage_agent/src/nat_alert_triage_agent/register.py
Show resolved
Hide resolved
Signed-off-by: Charlie Yi <charlie.yi@memverge.com>
|
@willkill07 We just cut a new release for memmachine-client to 0.3.0. This cut refactors memachine-client to no longer bundle some of memmachine-server so it should now be able to support python 3.11-3.14 |
|
/ok to test 5560585 |
Description
Add MemMachine as a memory plugin within NAT and also add a notebook example to demonstrate how to use MemMachine in NAT
By Submitting this PR I confirm:
Summary by CodeRabbit
New Features
Documentation
Improvements