Files
omnigent-ai--omnigent/tests/runner/test_hindsight_local_dispatch.py
2026-07-13 13:12:00 +08:00

104 lines
3.7 KiB
Python

"""Tests for routing the Hindsight memory builtins through runner-local dispatch.
Without runner-local dispatch a wrapped harness's (claude-sdk / codex / …) call
to hindsight_retain falls through to the harness, which has no such tool, and
silently no-ops. These lock in that the tools dispatch locally, are relayed to
native harnesses, and resolve the bank from the threaded agent identity.
"""
from __future__ import annotations
import asyncio
import json
from types import SimpleNamespace
from unittest.mock import MagicMock, patch
import pytest
from omnigent.runner.tool_dispatch import (
_ALL_LOCAL_TOOLS,
_HINDSIGHT_TOOLS,
_NATIVE_RELAY_BUILTIN_TOOLS,
_execute_hindsight_tool,
should_dispatch_locally,
)
def _spec(config: dict[str, str], name: str = "hindsight_retain") -> SimpleNamespace:
return SimpleNamespace(
executor=SimpleNamespace(model="claude-opus-4-8"),
tools=SimpleNamespace(builtins=[SimpleNamespace(name=name, config=config)]),
)
def test_hindsight_tool_set_is_exactly_the_three() -> None:
assert set(_HINDSIGHT_TOOLS) == {"hindsight_retain", "hindsight_recall", "hindsight_reflect"}
@pytest.mark.parametrize("name", ["hindsight_retain", "hindsight_recall", "hindsight_reflect"])
def test_hindsight_tools_are_runner_local(name: str) -> None:
assert name in _ALL_LOCAL_TOOLS
assert should_dispatch_locally(name) is True
@pytest.mark.parametrize("name", ["hindsight_retain", "hindsight_recall", "hindsight_reflect"])
def test_hindsight_tools_relayed_to_native_harnesses(name: str) -> None:
# Unlike web_search, native harnesses have no built-in memory of their own.
assert name in _NATIVE_RELAY_BUILTIN_TOOLS
def test_retain_dispatch_uses_agent_id_as_bank() -> None:
"""With no config bank_id, the bank defaults to the threaded agent_id."""
client = MagicMock()
spec = _spec({"api_key": "hsk_test"})
with patch("hindsight_client.Hindsight", return_value=client):
result = asyncio.run(
_execute_hindsight_tool(
{"content": "DuckDB is my favorite db"},
tool_name="hindsight_retain",
agent_spec=spec,
conversation_id="conv_1",
agent_id="ag_remy",
)
)
assert result == "Stored to long-term memory."
assert client.retain.call_args.kwargs["bank_id"] == "ag_remy"
assert client.retain.call_args.kwargs["content"] == "DuckDB is my favorite db"
def test_recall_dispatch_honors_config_bank_id() -> None:
"""An explicit config bank_id overrides the agent_id default."""
client = MagicMock()
response = MagicMock()
response.results = [MagicMock(text="DuckDB is my favorite db")]
client.recall.return_value = response
spec = _spec({"api_key": "hsk_test", "bank_id": "remy-ui-test"}, name="hindsight_recall")
with patch("hindsight_client.Hindsight", return_value=client):
result = asyncio.run(
_execute_hindsight_tool(
{"query": "favorite db"},
tool_name="hindsight_recall",
agent_spec=spec,
conversation_id="conv_1",
agent_id="ag_remy",
)
)
assert "DuckDB" in result
assert client.recall.call_args.kwargs["bank_id"] == "remy-ui-test"
def test_dispatch_missing_api_key_returns_error() -> None:
spec = _spec({}) # no api_key
result = asyncio.run(
_execute_hindsight_tool(
{"content": "x"},
tool_name="hindsight_retain",
agent_spec=spec,
agent_id="ag_remy",
)
)
assert "api_key" in result.lower()
# never echoes the success string when it couldn't store
assert result != "Stored to long-term memory."
json.dumps(result) # result is a plain string