From f6f1a7d8894b38fde139a2946b836df1f9348a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Boschi?= Date: Mon, 2 Mar 2026 10:32:01 +0100 Subject: [PATCH] fix: zeroentropy rerank URL missing /v1 prefix and MCP retain async_processing param (#460) * fix: zeroentropy rerank URL missing /v1 prefix and MCP routing tests - Fix ZeroEntropy reranker URL: /models/rerank -> /v1/models/rerank (#453) - Fix test_mcp_routing tests: update assertions to use submit_async_retain instead of the non-existent async_processing=False/retain_batch_async pattern * fix(openclaw): pass retainEveryNTurns through getPluginConfig and set it to 1 in tests getPluginConfig was not forwarding retainEveryNTurns from the raw config, so pluginConfig.retainEveryNTurns was always undefined (defaulting to 10). The integration tests use retainEveryNTurns: 1 so retain fires every turn. --- .../hindsight_api/engine/cross_encoder.py | 2 +- hindsight-api/tests/test_mcp_routing.py | 23 +++++++++---------- hindsight-integrations/openclaw/src/index.ts | 1 + .../openclaw/tests/hooks.integration.test.ts | 1 + 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/hindsight-api/hindsight_api/engine/cross_encoder.py b/hindsight-api/hindsight_api/engine/cross_encoder.py index 6d6016eb..610dfc1f 100644 --- a/hindsight-api/hindsight_api/engine/cross_encoder.py +++ b/hindsight-api/hindsight_api/engine/cross_encoder.py @@ -566,7 +566,7 @@ class ZeroEntropyCrossEncoder(CrossEncoderModel): See: https://docs.zeroentropy.dev/models """ - RERANK_URL = "https://api.zeroentropy.dev/models/rerank" + RERANK_URL = "https://api.zeroentropy.dev/v1/models/rerank" def __init__( self, diff --git a/hindsight-api/tests/test_mcp_routing.py b/hindsight-api/tests/test_mcp_routing.py index 8b89a1f7..01ae50c7 100644 --- a/hindsight-api/tests/test_mcp_routing.py +++ b/hindsight-api/tests/test_mcp_routing.py @@ -46,16 +46,15 @@ async def test_mcp_tools_use_context_bank_id(mock_memory): assert "retain" in tools assert "recall" in tools - # Test retain with bank_id from context (use async_processing=False for synchronous test) token = _current_bank_id.set("context-bank-id") try: retain_tool = tools["retain"] - result = await retain_tool.fn(content="test content", context="test_context", async_processing=False) - assert "successfully" in result.lower() + result = await retain_tool.fn(content="test content", context="test_context") + assert result["status"] == "accepted" # Verify the memory was called with the context bank_id - mock_memory.retain_batch_async.assert_called_once() - call_kwargs = mock_memory.retain_batch_async.call_args.kwargs + mock_memory.submit_async_retain.assert_called_once() + call_kwargs = mock_memory.submit_async_retain.call_args.kwargs assert call_kwargs["bank_id"] == "context-bank-id" finally: _current_bank_id.reset(token) @@ -133,12 +132,12 @@ async def test_mcp_tools_propagate_api_key(mock_memory): api_key_token = _current_api_key.set("test-bearer-token") try: retain_tool = tools["retain"] - result = await retain_tool.fn(content="test content", context="test_context", async_processing=False) - assert "successfully" in result.lower() + result = await retain_tool.fn(content="test content", context="test_context") + assert result["status"] == "accepted" # Verify the memory was called with request_context containing api_key - mock_memory.retain_batch_async.assert_called_once() - call_kwargs = mock_memory.retain_batch_async.call_args.kwargs + mock_memory.submit_async_retain.assert_called_once() + call_kwargs = mock_memory.submit_async_retain.call_args.kwargs assert call_kwargs["request_context"].api_key == "test-bearer-token" finally: _current_bank_id.reset(bank_token) @@ -200,11 +199,11 @@ async def test_mcp_tools_propagate_tenant_id_and_api_key_id(mock_memory): key_id_token = _current_api_key_id.set("key-uuid-456") try: retain_tool = tools["retain"] - await retain_tool.fn(content="test content", context="test_context", async_processing=False) + await retain_tool.fn(content="test content", context="test_context") # Verify the RequestContext passed to memory engine has all auth fields - mock_memory.retain_batch_async.assert_called_once() - request_context = mock_memory.retain_batch_async.call_args.kwargs["request_context"] + mock_memory.submit_async_retain.assert_called_once() + request_context = mock_memory.submit_async_retain.call_args.kwargs["request_context"] assert request_context.api_key == "hsk_test_key" assert request_context.tenant_id == "org-billing-123" assert request_context.api_key_id == "key-uuid-456" diff --git a/hindsight-integrations/openclaw/src/index.ts b/hindsight-integrations/openclaw/src/index.ts index 08db1404..bce77118 100644 --- a/hindsight-integrations/openclaw/src/index.ts +++ b/hindsight-integrations/openclaw/src/index.ts @@ -446,6 +446,7 @@ function getPluginConfig(api: MoltbotPluginAPI): PluginConfig { bankIdPrefix: config.bankIdPrefix, excludeProviders: Array.isArray(config.excludeProviders) ? config.excludeProviders : [], autoRecall: config.autoRecall !== false, // Default: true (on) — backward compatible + retainEveryNTurns: config.retainEveryNTurns, }; } diff --git a/hindsight-integrations/openclaw/tests/hooks.integration.test.ts b/hindsight-integrations/openclaw/tests/hooks.integration.test.ts index 6cc5a199..5f88e417 100644 --- a/hindsight-integrations/openclaw/tests/hooks.integration.test.ts +++ b/hindsight-integrations/openclaw/tests/hooks.integration.test.ts @@ -140,6 +140,7 @@ beforeAll(async () => { const handle = createMockApi({ dynamicBankId: true, excludeProviders: ['slack'], + retainEveryNTurns: 1, // retain every turn so individual tests aren't affected by chunking // No bankMission — keeps init lean }); triggerHook = handle.trigger;