Files
wehub-resource-sync c889a57b6b
Test Suites / Build CI Environment (push) Has been cancelled
Test Suites / Basic Tests (push) Has been cancelled
Test Suites / End-to-End Tests (push) Has been cancelled
Test Suites / CLI Tests (push) Has been cancelled
Test Suites / Slow End-to-End Tests (push) Has been cancelled
Test Suites / Graph Database Tests (push) Has been cancelled
Test Suites / Vector DB Tests (push) Has been cancelled
Test Suites / Temporal Graph Test (push) Has been cancelled
Test Suites / Search Test on Different DBs (push) Has been cancelled
Test Suites / Example Tests (push) Has been cancelled
Test Suites / Notebook Tests (push) Has been cancelled
Test Suites / OS and Python Tests Ubuntu (push) Has been cancelled
Test Suites / OS and Python Tests Extended (push) Has been cancelled
Test Suites / LLM Test Suite (push) Has been cancelled
Test Suites / S3 File Storage Test (push) Has been cancelled
Test Suites / Run Integration Tests (push) Has been cancelled
Test Suites / MCP Tests (push) Has been cancelled
Test Suites / Docker Compose Test (push) Has been cancelled
Test Suites / Docker CI test (push) Has been cancelled
Test Suites / Relational DB Migration Tests (push) Has been cancelled
Test Suites / Distributed Cognee Test (push) Has been cancelled
Test Suites / DB Examples Tests (push) Has been cancelled
Test Suites / Test Completion Status (push) Has been cancelled
Test Suites / Claude Code Review (push) Has been cancelled
Test Suites / basic checks (push) Has been cancelled
build | Build and Push Cognee MCP Docker Image to dockerhub / docker-build-and-push (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
build | Build and Push Docker Image to dockerhub / docker-build-and-push (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Core Functionality (3.11) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Core Functionality (3.12) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges with Different Graph Databases (kuzu, kuzu) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges with Different Graph Databases (neo4j, neo4j) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Examples (push) Has been cancelled
Weighted Edges Tests / Code Quality for Weighted Edges (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:02:24 +08:00

176 lines
6.5 KiB
Python

"""End-to-end tests for the public cognee.agent_memory feature."""
import os
from pathlib import Path
from uuid import uuid4
import pytest
import pytest_asyncio
import cognee
from cognee.exceptions import CogneeValidationError
from cognee.infrastructure.llm.LLMGateway import LLMGateway
from cognee.infrastructure.session.get_session_manager import get_session_manager
from cognee.modules.data.methods import create_authorized_dataset, get_datasets_by_name
from cognee.modules.engine.operations.setup import setup as engine_setup
from cognee.modules.users.methods import create_user
from cognee.modules.users.permissions.methods import authorized_give_permission_on_datasets
async def _reset_engines_and_prune() -> None:
"""Reset cached engines and clear persisted test state."""
try:
from cognee.infrastructure.databases.vector import get_vector_engine_async
vector_engine = await get_vector_engine_async()
if hasattr(vector_engine, "engine") and hasattr(vector_engine.engine, "dispose"):
await vector_engine.engine.dispose(close=True)
except Exception:
pass
from cognee.infrastructure.databases.graph.get_graph_engine import _create_graph_engine
from cognee.infrastructure.databases.relational.create_relational_engine import (
create_relational_engine,
)
from cognee.infrastructure.databases.vector.create_vector_engine import _create_vector_engine
_create_graph_engine.cache_clear()
_create_vector_engine.cache_clear()
create_relational_engine.cache_clear()
await cognee.prune.prune_data()
await cognee.prune.prune_system(metadata=True)
@pytest_asyncio.fixture
async def agent_memory_e2e_env(tmp_path):
"""Create a clean backend-access-controlled environment for agent-memory e2e tests."""
root = Path(tmp_path)
cognee.config.data_root_directory(str(root / "data"))
cognee.config.system_root_directory(str(root / "system"))
# Disable session-turn gating (auto_feedback). Memory retrieval runs with
# memory_only_context=False, so the turn analysis would otherwise intercept the retrieval
# query with a clarifying acknowledgement instead of returning the memory answer. The
# turn-gating layer has dedicated coverage (e.g. test_session_context_turn_flow.py).
prev_auto_feedback = os.environ.get("AUTO_FEEDBACK")
os.environ["AUTO_FEEDBACK"] = "False"
await _reset_engines_and_prune()
await engine_setup()
try:
yield
finally:
if prev_auto_feedback is None:
os.environ.pop("AUTO_FEEDBACK", None)
else:
os.environ["AUTO_FEEDBACK"] = prev_auto_feedback
await _reset_engines_and_prune()
@pytest.mark.asyncio
async def test_agent_memory_e2e_requires_write_then_retrieves_shared_memory(agent_memory_e2e_env):
"""Reject read-only access first and then retrieve shared memory after write access is granted."""
owner = await create_user(f"owner_{uuid4().hex[:8]}@example.com", "example")
member = await create_user(f"member_{uuid4().hex[:8]}@example.com", "example")
dataset_name = f"agent_memory_e2e_shared_{uuid4().hex[:8]}"
secret_codename = "Maple Panda"
await cognee.add(
[f"The private codename for this cognee agent_memory e2e test is '{secret_codename}'."],
dataset_name=dataset_name,
user=owner,
)
await cognee.cognify([dataset_name], user=owner)
dataset = (await get_datasets_by_name([dataset_name], owner.id))[0]
await authorized_give_permission_on_datasets(member.id, [dataset.id], "read", owner.id)
@cognee.agent_memory(
with_memory=True,
save_session_traces=False,
user=member,
dataset_name=dataset_name,
memory_query_fixed="What is the private codename for this cognee agent_memory e2e test?",
memory_system_prompt=(
"Return only the exact codename from memory context. "
"Do not shorten, summarize, or omit any part of it. "
"If no relevant context exists, return an empty string."
),
)
async def shared_memory_agent() -> str:
return await LLMGateway.acreate_structured_output(
text_input="What is the private codename for this cognee agent_memory e2e test?",
system_prompt=(
"Answer only with the exact codename from the available context. "
"If no context is available, return MISSING."
),
response_model=str,
)
with pytest.raises(CogneeValidationError, match="both read and write permissions"):
await shared_memory_agent()
await authorized_give_permission_on_datasets(member.id, [dataset.id], "write", owner.id)
result = await shared_memory_agent()
assert secret_codename in result
@pytest.mark.asyncio
async def test_agent_memory_e2e_persists_success_and_error_traces(agent_memory_e2e_env):
"""Persist both success and error trace steps through the public decorator path."""
owner = await create_user(f"owner_{uuid4().hex[:8]}@example.com", "example")
dataset_name = f"agent_memory_e2e_trace_{uuid4().hex[:8]}"
await create_authorized_dataset(dataset_name=dataset_name, user=owner)
success_text = f"agent-memory success {uuid4().hex[:8]}"
error_text = f"agent-memory failure {uuid4().hex[:8]}"
session_manager = get_session_manager()
session_id = f"trace-session-{uuid4().hex[:8]}"
@cognee.agent_memory(
with_memory=False,
save_session_traces=True,
user=owner,
dataset_name=dataset_name,
session_id=session_id,
)
async def successful_agent() -> str:
return success_text
@cognee.agent_memory(
with_memory=False,
save_session_traces=True,
user=owner,
dataset_name=dataset_name,
session_id=session_id,
)
async def failing_agent() -> str:
raise RuntimeError(error_text)
assert await successful_agent() == success_text
with pytest.raises(RuntimeError, match=error_text):
await failing_agent()
trace_entries = await session_manager.get_agent_trace_session(
user_id=str(owner.id),
session_id=session_id,
)
assert len(trace_entries) == 2
success_entry, error_entry = trace_entries
assert success_entry.origin_function.endswith("successful_agent")
assert success_entry.status == "success"
assert success_entry.method_return_value == success_text
assert success_entry.error_message == ""
assert error_entry.origin_function.endswith("failing_agent")
assert error_entry.status == "error"
assert error_entry.error_message == error_text