Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions tests/cross_runtime/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## Cross-Runtime Integration Tests

The `tests/cross_runtime/` test suite verifies that `.soul` files can be successfully exported to and imported from third-party agent frameworks without losing Core Memory, Semantic Memory, or Episodic Memory.
Comment thread
Akshat-Raj marked this conversation as resolved.

Currently supported frameworks and CLIs:
* **LangChain** (`langchain_core`)
* **CrewAI** (`crewai`)
* **PocketPaw** (via the `soul-protocol` Python Runtime API)

### Running the Tests

To run these integration tests locally, execute:

```bash
uv run pytest tests/cross_runtime/ -v
```

Optional Dependencies:
To keep the core soul-protocol lightweight, third-party frameworks like LangChain and CrewAI are not strictly required in the default development environment. If LangChain or CrewAI is not installed then the tests will skip instead of failing.

Python Version Constraints: The crewai ecosystem is currently unstable on newer Python runtimes.

These tests will automatically run and pass in the official CI pipeline under supported environments (Python <= 3.12). To run the full suite locally without skips, ensure those specific packages are installed and you are using a compatible Python version.
2 changes: 2 additions & 0 deletions tests/cross_runtime/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def pytest_configure(config):
config.addinivalue_line("markers", "cross_runtime: marks tests for .soul round-trip")
39 changes: 39 additions & 0 deletions tests/cross_runtime/test_crewai.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import pytest

from soul_protocol import Soul

pytest.importorskip("crewai", reason="CrewAI is not installed, skipping integration test.")
from crewai import Agent


@pytest.mark.cross_runtime
@pytest.mark.asyncio
async def test_crewai_integration(tmp_soul_file, tmp_path):
"""A populated soul file must be exported and then imported and must contain the correct persona."""

source_file = tmp_soul_file
soul = await Soul.awaken(source_file)

await soul.edit_core_memory(persona="CrewAI Agent")
await soul.note("User's favorite framework is CrewAI")

crew_agent = Agent(
role="Programmer",
goal="Write code",
backstory=soul.to_system_prompt(),
verbose=False,
allow_delegation=False,
)

assert "CrewAI Agent" in crew_agent.backstory

destination_file = str(tmp_path / "crewai_exported.soul")
await soul.export(destination_file)

recovered_soul = await Soul.awaken(destination_file)
assert "CrewAI Agent" in recovered_soul.to_system_prompt()

memories = await recovered_soul.recall("favorite framework")
assert any("favorite framework is CrewAI" in m.content for m in memories), (
"Semantic memory failed to persist"
)
33 changes: 33 additions & 0 deletions tests/cross_runtime/test_langchain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import pytest

from soul_protocol import Soul

pytest.importorskip(
"langchain_core", reason="LangChain is not installed, skipping integration test."
)
from langchain_core.messages import SystemMessage


@pytest.mark.cross_runtime
@pytest.mark.asyncio
async def test_langchain_integration(tmp_soul_file, tmp_path):
"""A populated soul file must be exported and then imported and must contain the correct persona."""

source_file = tmp_soul_file
soul = await Soul.awaken(source_file)

await soul.edit_core_memory(persona="LangChain Agent")
await soul.note("User's favorite framework is LangChain")
langchain_message = SystemMessage(content=soul.to_system_prompt())

assert "LangChain Agent" in langchain_message.content
destination_file = str(tmp_path / "langchain_exported.soul")

await soul.export(destination_file)
recovered_soul = await Soul.awaken(destination_file)
assert "LangChain Agent" in recovered_soul.to_system_prompt()

memories = await recovered_soul.recall("favorite framework")
assert any("favorite framework is LangChain" in m.content for m in memories), (
"Semantic memory failed to persist"
)
38 changes: 38 additions & 0 deletions tests/cross_runtime/test_pocketpaw.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import pytest

from soul_protocol import Soul

pytest.importorskip("pocketpaw", reason="Pocketpaw is not installed, skipping integration test.")
from pocketpaw.config import Settings
from pocketpaw.soul.manager import SoulManager


@pytest.mark.cross_runtime
@pytest.mark.asyncio
async def test_pocketpaw_integration(tmp_soul_file, tmp_path):
"""A populated soul file must be exported and then imported by pocketpaw and must contain the correct persona."""

source_file = tmp_soul_file
soul = await Soul.awaken(source_file)
Comment thread
Akshat-Raj marked this conversation as resolved.

await soul.edit_core_memory(persona="PocketPaw Agent")
await soul.note("User is using soul-protocol")

exported_file = str(tmp_path / "pocketpaw_exported.soul")
await soul.export(exported_file)

settings = Settings(
soul_path=str(tmp_path / "pocketpaw_loaded.soul"), soul_name="pocketpaw_loaded"
)
manager = SoulManager(settings)
await manager.import_from_file(exported_file)

assert manager.soul is not None, "PocketPaw failed to load the soul"
assert manager.soul.get_core_memory().persona == "PocketPaw Agent", (
"Core memory failed to persist through PocketPaw import"
)

memories = await manager.soul.recall("soul-protocol")
assert any("soul-protocol" in m.content for m in memories), (
"Sequential memory failed to persist"
)