diff --git a/plugins/_memory/AGENTS.md b/plugins/_memory/AGENTS.md index 622026f57..061b4a463 100644 --- a/plugins/_memory/AGENTS.md +++ b/plugins/_memory/AGENTS.md @@ -16,6 +16,7 @@ - Keep memory scoped by configured subdirectory/context. - Preserve embedding metadata needed to rebuild indexes safely. +- `memory_load` accepts numeric `threshold` and `limit` values as native numbers or numeric strings and coerces them before vector search. - Avoid storing transient action-history noise as durable memory. ## Work Guidance diff --git a/plugins/_memory/tools/memory_load.py b/plugins/_memory/tools/memory_load.py index 9305186f6..7fe419c16 100644 --- a/plugins/_memory/tools/memory_load.py +++ b/plugins/_memory/tools/memory_load.py @@ -8,6 +8,13 @@ DEFAULT_LIMIT = 10 class MemoryLoad(Tool): async def execute(self, query="", threshold=DEFAULT_THRESHOLD, limit=DEFAULT_LIMIT, filter="", **kwargs): + if threshold is None or threshold == "": + threshold = DEFAULT_THRESHOLD + if limit is None or limit == "": + limit = DEFAULT_LIMIT + threshold = float(threshold) + limit = int(limit) + db = await Memory.get(self.agent) docs = await db.search_similarity_threshold(query=query, limit=limit, threshold=threshold, filter=filter) diff --git a/tests/test_tool_action_contracts.py b/tests/test_tool_action_contracts.py index 4e964130f..ed21388cc 100644 --- a/tests/test_tool_action_contracts.py +++ b/tests/test_tool_action_contracts.py @@ -548,6 +548,54 @@ def test_memory_forget_tool_imports_plugin_memory_load(monkeypatch): ] +def test_memory_load_coerces_numeric_string_args(monkeypatch): + _install_tool_stub(monkeypatch) + monkeypatch.syspath_prepend(str(Path.cwd())) + + class FakeDb: + def __init__(self) -> None: + self.calls = [] + + async def search_similarity_threshold(self, **kwargs): + self.calls.append(kwargs) + return [] + + fake_db = FakeDb() + + async def get_memory(_agent): + return fake_db + + memory_stub = types.ModuleType("plugins._memory.helpers.memory") + memory_stub.Memory = types.SimpleNamespace(get=get_memory) + monkeypatch.setitem(sys.modules, "plugins._memory.helpers.memory", memory_stub) + + sys.modules.pop("plugins._memory.tools.memory_load", None) + module = importlib.import_module("plugins._memory.tools.memory_load") + tool = module.MemoryLoad( + _FakeAgent(), + "memory_load", + None, + { + "query": "smoke test project context", + "threshold": "0.7", + "limit": "3", + }, + "", + None, + ) + + asyncio.run(tool.execute(**tool.args)) + + assert fake_db.calls == [ + { + "query": "smoke test project context", + "threshold": 0.7, + "limit": 3, + "filter": "", + } + ] + + def test_behaviour_adjustment_normalizes_duplicate_rules(monkeypatch): _install_tool_stub(monkeypatch) monkeypatch.syspath_prepend(str(Path.cwd()))