Files
semantica/tests/integrations/langchain/test_degradation.py
T
Derek TapleyandCursor f0aa581318 feat(integrations): add LangChain integration — retriever, vectorstor… (#1155)
* feat(integrations): add LangChain integration — retriever, vectorstore, tools

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(langchain): address Qodo review on HybridSearch hits and tools

Read nested HybridSearch metadata so retriever/vectorstore Documents
are not empty, make the agent tools real BaseTool subclasses, and
stop slicing tool JSON into invalid payloads.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-26 18:29:22 +05:00

93 lines
2.7 KiB
Python

"""
Graceful-degradation tests for the LangChain integration.
Runs the adapters in a fresh subprocess with langchain-core hidden, so the
object-base path is proven even when this env has langchain-core installed.
"""
from __future__ import annotations
import os
import subprocess
import sys
from types import SimpleNamespace
import pytest
from integrations.langchain import (
LANGCHAIN_AVAILABLE,
SemanticaDecisionTool,
SemanticaKGTool,
)
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
_SCRIPT = r"""
import sys
from types import SimpleNamespace
class _BlockLangchain:
def find_spec(self, fullname, path=None, target=None):
if fullname == "langchain_core" or fullname.startswith("langchain_core."):
raise ImportError("langchain_core blocked for degradation test")
return None
sys.meta_path.insert(0, _BlockLangchain())
for name in list(sys.modules):
if name == "langchain_core" or name.startswith("langchain_core."):
del sys.modules[name]
from integrations.langchain.retriever import LANGCHAIN_AVAILABLE as RET_AVAIL
from integrations.langchain.vectorstore import (
LANGCHAIN_AVAILABLE as VS_AVAIL,
SemanticaVectorStore,
)
from integrations.langchain.tools import (
LANGCHAIN_AVAILABLE as TOOL_AVAIL,
SemanticaKGTool,
SemanticaDecisionTool,
)
from integrations.langchain.retriever import SemanticaRetriever, _get_document
assert RET_AVAIL is False and VS_AVAIL is False and TOOL_AVAIL is False
retriever = SemanticaRetriever(graph=SimpleNamespace(), hops=2)
assert retriever.hops == 2
store = SemanticaVectorStore(hybrid=SimpleNamespace(), tags=["x"])
assert store.hybrid is not None
graph = SimpleNamespace(query=lambda q, limit=10: [{"q": q, "limit": limit}])
assert SemanticaKGTool(graph).build() is None
assert SemanticaDecisionTool(graph).build() is None
try:
_get_document(page_content="x")
raise SystemExit("expected RuntimeError from _get_document")
except RuntimeError as exc:
assert "langchain-core" in str(exc)
print("DEGRADATION_OK")
"""
def test_importable_and_functional_without_langchain():
result = subprocess.run(
[sys.executable, "-c", _SCRIPT],
cwd=REPO_ROOT,
capture_output=True,
text=True,
timeout=60,
)
assert result.returncode == 0, (
f"subprocess failed:\nSTDOUT:\n{result.stdout}\nSTDERR:\n{result.stderr}"
)
assert "DEGRADATION_OK" in result.stdout
@pytest.mark.skipif(LANGCHAIN_AVAILABLE, reason="langchain-core is installed")
def test_tools_build_returns_none_without_langchain():
graph = SimpleNamespace()
assert SemanticaKGTool(graph).build() is None
assert SemanticaDecisionTool(graph).build() is None