Skip to content

Commit afc1c79

Browse files
authored
Merge branch 'develop' into fk/oci-langchain-nemotron
2 parents 88efe28 + 0bf30ad commit afc1c79

File tree

9 files changed

+26
-15
lines changed

9 files changed

+26
-15
lines changed

docs/source/build-workflows/memory.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ The memory module is designed to be extensible, allowing developers to create cu
2424
## Included Memory Modules
2525
The NeMo Agent Toolkit includes four memory module providers, all of which are available as plugins:
2626
* [Mem0](https://mem0.ai/) which is provided by the [`nvidia-nat-mem0ai`](https://pypi.org/project/nvidia-nat-mem0ai/) plugin.
27-
* [MemMachine](https://memmachine.ai/) which is provided by the [`nvidia-nat-memmachine`](https://pypi.org/project/nvidia-nat-memmachine/) plugin.
27+
* [MemMachine](https://memmachine.ai/) which is provided by the [`nvidia-nat-memmachine`](https://pypi.org/project/nvidia-nat-memmachine/) plugin (**Experimental; not recommended for production use**).
2828
* [Redis](https://redis.io/) which is provided by the [`nvidia-nat-redis`](https://pypi.org/project/nvidia-nat-redis/) plugin.
2929
* [Zep](https://www.getzep.com/) which is provided by the [`nvidia-nat-zep-cloud`](https://pypi.org/project/nvidia-nat-zep-cloud/) plugin ([Zep NVIDIA NeMo documentation](https://help.getzep.com/nvidia-nemo)).
3030

docs/source/build-workflows/workflow-configuration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ This section contains the evaluation settings for the workflow. Refer to [Evalua
112112

113113
### `memory`
114114

115-
This section configures long-term memory backends such as [Mem0](https://mem0.ai/) or [MemMachine](https://memmachine.ai/). It follows the same format as the `llms` section. Refer to the [Memory Module](./memory.md) document for supported providers and examples.
115+
This section configures long-term memory backends such as [Mem0](https://mem0.ai/) or [MemMachine](https://memmachine.ai/) (note: MemMachine is experimental and is not recommended for production use). It follows the same format as the `llms` section. Refer to the [Memory Module](./memory.md) document for supported providers and examples.
116116

117117
### `retrievers`
118118

docs/source/components/agents/auto-memory-wrapper/auto-memory-wrapper.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ The automatic memory wrapper agent works with any memory backend that implements
2525

2626
- [`nvidia-nat-zep-cloud`](https://pypi.org/project/nvidia-nat-zep-cloud/) - Zep Cloud memory backend ([Zep NVIDIA NeMo documentation](https://help.getzep.com/nvidia-nemo))
2727
- [`nvidia-nat-mem0ai`](https://pypi.org/project/nvidia-nat-mem0ai/) - Mem0 memory backend
28-
- [`nvidia-nat-memmachine`](https://pypi.org/project/nvidia-nat-memmachine/) - MemMachine memory backend ([MemMachine documentation](https://docs.memmachine.ai/))
28+
- [`nvidia-nat-memmachine`](https://pypi.org/project/nvidia-nat-memmachine/) - MemMachine memory backend (**Experimental; not recommended for production use**) ([MemMachine documentation](https://docs.memmachine.ai/))
2929
- [`nvidia-nat-redis`](https://pypi.org/project/nvidia-nat-redis/) - Redis memory backend
3030

3131
## Configuration

docs/source/get-started/installation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ To install these first-party plugin libraries, you can use the full distribution
4545
- `nvidia-nat[llama-index]` or `nvidia-nat-llama-index` - [LlamaIndex](https://www.llamaindex.ai/)
4646
- `nvidia-nat[mcp]` or `nvidia-nat-mcp` - [Model Context Protocol (MCP)](https://modelcontextprotocol.io/)
4747
- `nvidia-nat[mem0ai]` or `nvidia-nat-mem0ai` - [Mem0](https://mem0.ai/)
48-
- `nvidia-nat[memmachine]` or `nvidia-nat-memmachine` - [MemMachine](https://memmachine.ai/)
48+
- `nvidia-nat[memmachine]` or `nvidia-nat-memmachine` - [MemMachine](https://memmachine.ai/) (**Experimental; not recommended for production use**)
4949
- `nvidia-nat[mysql]` or `nvidia-nat-mysql` - [MySQL](https://www.mysql.com/)
5050
- `nvidia-nat[config-optimizer]` or `nvidia-nat-config-optimizer` - Parameter and prompt optimizer (required for `nat optimize`)
5151
- `nvidia-nat[openpipe-art]` or `nvidia-nat-openpipe-art` - [Agent Reinforcement Trainer](https://art.openpipe.ai/getting-started/about) Conflicts with `nvidia-nat[adk]` and `nvidia-nat[crewai]`.

packages/nvidia_nat_memmachine/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ limitations under the License.
1919

2020
This package provides integration with MemMachine for memory management in NeMo Agent toolkit.
2121

22+
> [!WARNING]
23+
> **Experimental**: The `nvidia-nat-memmachine` plugin is Experimental and is not recommended for production use. Behavior may change without notice.
24+
2225
## Overview
2326

2427
MemMachine is a unified memory management system that supports both episodic and semantic memory through a single interface. This integration allows you to use MemMachine as a memory backend for your NeMo Agent toolkit workflows.

packages/nvidia_nat_memmachine/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ license = { text = "Apache-2.0" }
4040
authors = [{ name = "NVIDIA Corporation" }]
4141
maintainers = [{ name = "NVIDIA Corporation" }]
4242
classifiers = [
43+
"Development Status :: 3 - Alpha",
4344
"Programming Language :: Python",
4445
"Programming Language :: Python :: 3.11",
4546
"Programming Language :: Python :: 3.12",

packages/nvidia_nat_memmachine/src/nat/meta/pypi.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,8 @@ limitations under the License.
2020
# NVIDIA NeMo Agent toolkit Subpackage
2121
This is a subpackage for MemMachine memory integration in NeMo Agent toolkit.
2222

23+
> [!WARNING]
24+
> **Experimental**: The `nvidia-nat-memmachine` plugin is Experimental and is not recommended for production use. Behavior may change without notice.
25+
2326
For more information about the NVIDIA NeMo Agent toolkit, please visit the [NeMo Agent toolkit GitHub Repo](https://github.com/NVIDIA/NeMo-Agent-Toolkit).
2427

packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memmachine_editor.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,14 @@ async def add_items(self, items: list[MemoryItem]) -> None:
111111
Each MemoryItem is translated and uploaded through the MemMachine API.
112112
113113
All memories are added to both episodic and semantic memory types.
114+
115+
Conversation messages within a single MemoryItem are added sequentially to
116+
preserve chronological order. Separate MemoryItems (and non-conversation
117+
memories) are still dispatched concurrently via asyncio.gather.
114118
"""
115-
# Run synchronous operations in thread pool to make them async
116-
tasks = []
117119

118-
for memory_item in items:
120+
async def add_item(memory_item: MemoryItem) -> None:
121+
"""Upload a single MemoryItem, adding conversation messages sequentially."""
119122
# Make a copy of metadata to avoid modifying the original
120123
item_meta = memory_item.metadata.copy() if memory_item.metadata else {}
121124
conversation = memory_item.conversation
@@ -139,7 +142,9 @@ async def add_items(self, items: list[MemoryItem]) -> None:
139142
# If we have a conversation, add each message separately
140143
# Otherwise, use memory_text or skip if no content
141144
if conversation:
142-
# Add each message in the conversation with its role
145+
# Add each message sequentially to preserve conversation order.
146+
# asyncio.to_thread tasks dispatched via gather() complete in
147+
# nondeterministic order, so we await each one before the next.
143148
for msg in conversation:
144149
msg_role = msg.get('role', 'user')
145150
msg_content = msg.get('content', '')
@@ -154,7 +159,6 @@ async def add_items(self, items: list[MemoryItem]) -> None:
154159
# Convert list to comma-separated string
155160
metadata["tags"] = ", ".join(tags) if isinstance(tags, list) else str(tags)
156161

157-
# Capture variables in closure to avoid late binding issues
158162
def add_memory(
159163
content=msg_content,
160164
role=msg_role,
@@ -173,8 +177,7 @@ def add_memory(
173177
episode_type=None # Use default (MESSAGE)
174178
)
175179

176-
task = asyncio.to_thread(add_memory)
177-
tasks.append(task)
180+
await asyncio.to_thread(add_memory)
178181
elif memory_text:
179182
# Add as a single memory item (direct memory without conversation)
180183
# Add tags to metadata if present
@@ -195,11 +198,10 @@ def add_memory(content=memory_text, mem=memory, meta=metadata, mem_types=memory_
195198
episode_type=None # Use default (MESSAGE)
196199
)
197200

198-
task = asyncio.to_thread(add_memory)
199-
tasks.append(task)
201+
await asyncio.to_thread(add_memory)
200202

201-
if tasks:
202-
await asyncio.gather(*tasks)
203+
if items:
204+
await asyncio.gather(*(add_item(item) for item in items))
203205

204206
async def search(self, query: str, top_k: int = 5, **kwargs) -> list[MemoryItem]:
205207
"""

packages/nvidia_nat_memmachine/src/nat/plugins/memmachine/memory.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from nat.cli.register_workflow import register_memory
2121
from nat.data_models.memory import MemoryBaseConfig
2222
from nat.data_models.retry_mixin import RetryMixin
23+
from nat.experimental.decorators.experimental_warning_decorator import experimental
2324
from nat.memory.interfaces import MemoryEditor
2425
from nat.utils.exception_handlers.automatic_retries import patch_with_retry
2526

@@ -45,6 +46,7 @@ class MemMachineMemoryClientConfig(MemoryBaseConfig, RetryMixin, name="memmachin
4546

4647

4748
@register_memory(config_type=MemMachineMemoryClientConfig)
49+
@experimental(feature_name="MemMachine")
4850
async def memmachine_memory_client(
4951
config: MemMachineMemoryClientConfig,
5052
_builder: Builder, # Required by @register_memory contract

0 commit comments

Comments
 (0)