Metadata-Version: 2.5
Name: langgraph-store-postgres
Version: 0.1.0
Summary: PostgreSQL long-term-memory store (BaseStore) for LangGraph — namespaced key/value memory with filters, list_namespaces and native semantic (pgvector) search
Project-URL: Homepage, https://github.com/skamalj/langgraph-store
Project-URL: Repository, https://github.com/skamalj/langgraph-store.git
Author-email: Kamal <skamalj@gmail.com>
Keywords: agent-memory,basestore,langgraph,long-term-memory,postgres,postgresql,store
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.10
Requires-Dist: langgraph-store-core>=0.1.0
Requires-Dist: pgvector>=0.2
Requires-Dist: psycopg2-binary
Requires-Dist: sqlalchemy>=2.0
Description-Content-Type: text/markdown

# langgraph-store-postgres

A **PostgreSQL** long-term-memory store (`BaseStore`) for [LangGraph](https://langchain-ai.github.io/langgraph/) — namespaced key/value memory with prefix search, filters, `list_namespaces`, and **native semantic search via pgvector**.

```bash
pip install langgraph-store-postgres
```

```python
from langgraph_store_postgres import PostgresStore

store = PostgresStore("postgresql://user:pass@localhost:5432/db")   # or engine=<Engine>

store.put(("users", "1", "memories"), "food", {"text": "loves sushi", "kind": "pref"})
item = store.get(("users", "1", "memories"), "food")
hits = store.search(("users", "1"), filter={"kind": "pref"}, limit=10)
spaces = store.list_namespaces(prefix=("users",))
```

Use it as a LangGraph store: `graph.compile(store=PostgresStore(...))`. Async methods (`aget`/`aput`/`asearch`/…) work too — the sync calls run in a thread.

## Semantic search (pgvector)

Pass a LangGraph `IndexConfig` and the store embeds the configured fields on `put` and ranks `search(query=...)` by cosine similarity using pgvector (`<=>`, HNSW index):

```python
from langgraph_store_core import bedrock_titan_embeddings
from langgraph_store_postgres import PostgresStore

store = PostgresStore(url, table_name="memory",
                      index={"dims": 1024, "embed": bedrock_titan_embeddings(dimensions=1024), "fields": ["text"]})
store.put(("memories", "kamal"), "k1", {"text": "the user loves sushi", "kind": "pref"})
hits = store.search(("memories", "kamal"), query="what food does the user like?", filter={"kind": "pref"})
print(hits[0].score, hits[0].value)
```

`embed` may be any LangChain `Embeddings`, a `list[str] -> list[list[float]]` callable, or a provider string. `fields` defaults to `["$"]` (whole value as JSON). `put(..., index=False)` skips embedding for one item.

Requires the [pgvector](https://github.com/pgvector/pgvector) extension on the server (`apt install postgresql-16-pgvector`, or built in on RDS / Cloud SQL / Azure Database). The store runs `CREATE EXTENSION IF NOT EXISTS vector`, adds an `embedding vector(dims)` column and an HNSW cosine index. Namespace prefix and plain-equality filters run inside the SQL query (JSONB containment); operator filters (`$gt`, `$in`, …) are applied on the returned candidates.

## Data model

A single table `(prefix, key, value JSONB, created_at, updated_at[, embedding vector])` with primary key `(prefix, key)`, created automatically. Namespace tuples are joined with a unit separator into `prefix`; search is a prefix scan, filters and namespace matching are evaluated in the [core](https://pypi.org/project/langgraph-store-core/).

Docs: <https://skamalj.github.io/agentstate-reducer/>

## License

MIT
