Metadata-Version: 2.4
Name: langchain-schift
Version: 0.1.0
Summary: An integration package connecting Schift and LangChain
Project-URL: Homepage, https://schift.io
Project-URL: Repository, https://github.com/schift-io/langchain-schift
Project-URL: Documentation, https://docs.schift.io/integrations/langchain
Author-email: Schift <hello@schift.io>
License-Expression: MIT
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Requires-Dist: langchain-core<1.0.0,>=0.3.0
Requires-Dist: schift>=0.2.0
Provides-Extra: dev
Requires-Dist: mypy>=1.10.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.5.0; extra == 'dev'
Description-Content-Type: text/markdown

# langchain-schift

LangChain integration for [Schift](https://schift.io) -- vector store with server-side embedding and graph edges.

## Installation

```bash
pip install langchain-schift
```

## Quick Start

Schift handles embedding server-side, so **no Embeddings object is needed**:

```python
from langchain_schift import SchiftVectorStore

store = SchiftVectorStore(
    api_key="sk-...",
    bucket="my-bucket",
)

# Add documents (embedded server-side)
store.add_texts(["Contract A supersedes Contract B", "Contract B dated 2024-01"])

# Search
results = store.similarity_search("which contract is newer?", k=3)
```

## Graph-Enhanced Retrieval

Schift supports edges between documents. This is useful for legal citations, document versioning, knowledge graphs, and more:

```python
# Add edges between documents
store.add_edges([
    {"source": "contract-a", "target": "contract-b", "relation": "supersedes"},
    {"source": "clause-1", "target": "contract-a", "relation": "has_child"},
])

# Search with graph expansion -- follows edges from top results
results = store.similarity_search(
    "contract terms",
    k=5,
    graph_expand=True,
    graph_depth=1,
    graph_relations=["supersedes", "has_child"],
)
```

Supported relation types: `contradicts`, `supersedes`, `caused_by`, `is_a`, `related_to`, `has_child`, `follows`.

## Use with LangChain chains

```python
from langchain_schift import SchiftVectorStore
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

store = SchiftVectorStore(api_key="sk-...", bucket="legal-docs")
retriever = store.as_retriever(search_kwargs={"k": 5})

# Use in a chain
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser

prompt = ChatPromptTemplate.from_template(
    "Answer based on context:\n{context}\n\nQuestion: {question}"
)
llm = ChatOpenAI()

chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

answer = chain.invoke("What are the key contract terms?")
```

## Modes

| Mode | Use case | Embedding |
|------|----------|-----------|
| **Bucket** (recommended) | Upload files/texts, Schift handles everything | Server-side |
| **Collection** | Raw vector operations with your own embeddings | Client-side or server-side |

```python
# Bucket mode (server-side embedding)
store = SchiftVectorStore(api_key="sk-...", bucket="my-bucket")

# Collection mode (bring your own embeddings)
from langchain_openai import OpenAIEmbeddings
store = SchiftVectorStore(
    api_key="sk-...",
    collection="my-collection",
    embedding=OpenAIEmbeddings(),
)
```

## Environment Variables

Set `SCHIFT_API_KEY` to avoid passing `api_key` explicitly:

```bash
export SCHIFT_API_KEY=sk-...
```
