Skip to content

feat: LangChain integration for Python SDK - #69

Merged
jsam merged 23 commits into
mainfrom
feat/langchain-integration
Apr 13, 2026
Merged

jsam merged 23 commits into
mainfrom
feat/langchain-integration

Conversation

@alessandrostone

@alessandrostone alessandrostone commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

LangChain integration for the Python SDK

This PR adds first-class LangChain support to the Python client, letting you plug an InputLayer knowledge graph into any LangChain chain, agent, or pipeline with a few lines of code.

What's included

Integration components (src/inputlayer/integrations/langchain/)

  • InputLayerRetriever - a BaseRetriever with two modes. IQL mode gives full query control with safe :placeholder parameter binding. Vector mode auto-detects the Vector column on a Relation, embeds the user query, and ranks by distance - all composed as IQL under the hood.
  • InputLayerVectorStore - a full VectorStore implementation that maps a typed Relation schema to LangChain's add_texts / similarity_search / delete / MMR interface.
  • tools_from_relations - generates one StructuredTool per Relation with a typed Pydantic args schema derived from the relation's scalar columns. The LLM never writes IQL; it picks structured arguments and the tool builds the query.
  • InputLayerIQLTool - escape hatch for agents that need to run raw IQL.
  • bind_params / iql_literal - safe parameter binding that prevents IQL injection.

Sync/async bridge (src/inputlayer/_sync.py)

Replaces the old run_until_complete pattern with a dedicated background event loop thread (same pattern as httpx). The sync client now works inside Jupyter, FastAPI, LangGraph, and any context with an already-running event loop.

17 examples

The examples are designed to show patterns that only become possible when you combine an LLM with a reasoning engine. Each one runs against a real InputLayer server - no mocks.

# Example What it demonstrates
1 IQL Retriever InputLayerRetriever with an article JOIN user_interest query and safe :input placeholder binding
2 Vector Search Vector mode - embed, search, rank by cosine distance
3 Agent Tool tools_from_relations generates typed tools an agent can call without writing IQL
4 LCEL Chain Full retriever | prompt | llm | parser pipeline, drop-in compatible with LangChain composition
5 KG Building Reverses the RAG flow: LLM extracts structured facts from documents, VectorStore.aadd_texts embeds and persists them
6 Explainable RAG .why() returns structured proof trees alongside results so the LLM can cite specific base facts; .why_not() explains absent results
7 Multi-hop Reasoning Recursive IQL rules compute transitive closure (chain of command over reports_to); the LLM reads pre-computed derived facts instead of doing graph traversal itself
8 Conversational Memory Chat turns stored as facts, IQL rules derive topic context and conversation state
9 Access-controlled RAG Clearance-based document filtering enforced as an IQL join - no application-level post-filtering, same retriever returns different docs per user
10 Multi-agent Two agents share a KG without direct communication. Researcher writes claims, IQL rules instantly classify them as verified or contradicted against ground truth
11 Anomaly Detection Salary band rules flag violations, LLM explains the anomalies
12 Hallucination Detection LLM answers a question, claims are extracted, IQL rules cross-reference each claim against ground truth to produce grounded_claim and hallucinated_claim sets
13 Guardrails Policy rules block unsafe content and PII before the LLM sees it
14 GraphRAG Microsoft GraphRAG pattern - LLM extracts entities/relationships, IQL rules compute communities, LLM summarizes each community for corpus-level questions
15 Semantic Caching Cache LLM responses as facts, retrieve by topic similarity
16 Recommendation Collaborative filtering via IQL rules
17 Data Lineage Every claim links to a reliability-rated source; IQL rules compute multi_sourced (2+ sources confirm) and conflict (same subject, different values)

Running the examples

pip install inputlayer-client-dev[langchain]

# List all examples
uv run python -m examples.langchain.runner --list

# Run specific examples (1 and 3 don't need an LLM)
uv run python -m examples.langchain.runner 1 3

# Run an LLM-dependent example with LM Studio
LLM_MODEL=... uv run python -m examples.langchain.runner 4

Usage

from inputlayer.integrations.langchain import InputLayerRetriever

retriever = InputLayerRetriever(
    kg=kg,
    query='?article(Id, Title, Content, Cat, Emb), user_interest(":input", Cat)',
    page_content_columns=["content"],
    metadata_columns=["title", "category"],
)
chain = retriever | prompt | llm | StrOutputParser()

Other changes

  • Dev tooling: ruff, mypy (strict), uv project setup
  • CI: added Python langchain integration (live server) workflow
  • Docs: LangChain guide at docs/content/docs/guides/langchain.mdx
  • Exception renames: ConnectionError / PermissionError renamed to InputLayerConnectionError / InputLayerPermissionError (old names kept as aliases) to avoid shadowing Python builtins
  • QueryError export: now available from the top-level package
  • Metric validation: invalid distance metrics raise ValueError instead of silently defaulting to cosine
  • Structured logging: DEBUG-level logging at all IQL execution points for production troubleshooting

Test plan

  • uv run pytest tests/test_sync.py - 44 sync bridge tests
  • uv run pytest tests/test_langchain.py - 119 LangChain integration tests (unit) + 5 live server tests
  • uv run pytest tests/test_compiler.py - 59 compiler tests
  • Full suite: 610 passed, 15 skipped
  • CI: all checks green including live server integration

… wrapper

  The old sync wrapper crashed inside running event loops (Jupyter, FastAPI,
  LangGraph). Uses a dedicated daemon thread with its own loop instead —
  same pattern as httpx. Prerequisite for LangChain integration.
  InputLayerRetriever supports raw Datalog queries with {input} placeholder
  and vector search mode. InputLayerTool exposes KG queries to LangChain agents.
  Both provide native async and sync paths via the run_sync bridge.
@alessandrostone
alessandrostone requested a review from jsam April 2, 2026 06:24
@jsam jsam changed the title Feat/langchain integration feat: LangChain integration for Python SDK Apr 10, 2026
@jsam
jsam merged commit a410bf2 into main Apr 13, 2026
11 checks passed
@jsam
jsam deleted the feat/langchain-integration branch April 13, 2026 12:39
jsam added a commit that referenced this pull request Sep 4, 2026
* chore(deps): resolve every open Dependabot alert across npm and pip manifests

131 open alerts, six manifests, all npm or pip (no Cargo alerts).

front: next 16.2.1 -> 16.2.11, postcss ^8.5.23; nanoid and sharp via audit fix.
demo: hono ^4.12.34, ws ^8.21.0, nodemailer ^6 -> ^9 (createTransport and
  sendMail are unchanged); esbuild and follow-redirects via update.
inputlayer-js: ws ^8.21.0; vite, vitest, postcss, nanoid, picomatch via
  update; esbuild pinned to ^0.28.1 through an override because tsup's range
  still admits the vulnerable line.
api-client: orval ^8.5 -> ^8.22 (two import-time RCEs and an SSRF);
  fast-uri, js-yaml, linkify-it, markdown-it, brace-expansion, picomatch
  via update; same esbuild override.
inputlayer-py: idna, langchain-core, langchain-openai, langgraph-checkpoint,
  langgraph-sdk, langsmith, pytest, urllib3 relocked. langsmith's patched
  line needs websockets >= 15, so the bound widens to >=13,<16; the client
  already imports websockets.asyncio.client, which is the API that survives.

Removed docs/site: a Nextra 2 skeleton with no pages directory and no
lockfile, last touched in #69, referenced by nothing in CI or the Makefile
(the live site is front/). It carried 15 Next.js 13 advisories no build
would ever exercise. Removed packages/api-client/bun.lock: out of sync with
package-lock.json, and nothing installs with bun.

Verified: npm audit reports 0 vulnerabilities in all four npm packages;
front builds; demo builds; inputlayer-js typechecks, builds, and passes 96
unit tests under Node 22; api-client builds; inputlayer-py passes 974 unit
tests.

* fix(deps): exact Next pin, targeted lockfiles, docs README after review

- front: Next pinned exactly at 16.3.4 (was loosened to a caret). 16.2.11
  closes the Next advisories but vendors postcss 8.5.22 and depends on
  sharp 0.34, both still flagged; 16.3.x is the first line where the
  vendored copies are patched, and it is what the earlier build actually
  ran against.
- demo, inputlayer-js, api-client: lockfiles rebuilt from main with only
  the flagged packages moved. Drops the unrelated @types/node 25 -> 26 and
  zod 3 -> 4 majors that a blanket npm update had swept in. Remaining
  majors are what the bumped packages themselves require (commander for
  orval 8.27) or were the alert (picomatch 2 -> 4).
- demo: esbuild override, same reason as the other two (tsx's range still
  admits the vulnerable line).
- vite in inputlayer-js resolved under Node 22: npm's engine check on
  Node 21 silently refused to move it past 7.3.1.
- docs/README.md and .gitignore no longer mention the removed docs/site.

Verified from clean installs: npm ci passes in all four packages; front
builds; demo builds; inputlayer-js typechecks, builds, 96 tests pass under
Node 22; api-client typechecks and builds; npm audit is 0 everywhere.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants