LangChain memory and retriever backed by OriginTrail DKG v10 Working Memory
Project description
langchain-dkg
LangChain memory and retriever backed by OriginTrail DKG v10 Working Memory.
Give any LangChain agent persistent, verifiable, queryable memory — every conversation turn stored as a cryptographically-linked Knowledge Asset on the Decentralized Knowledge Graph.
Demo
- Walkthrough video: youtu.be/7VEjDqflEpc — narrated run of all three components against a live DKG v10 node.
- Recording script:
examples/demo_video.py— the script behind the video.
Install
pip install langchain-dkg
Requires a running DKG v10 node. Install with:
npm install -g @origintrail-official/dkg
dkg init && dkg start
export DKG_TOKEN=$(dkg auth show)
Quick start
from langchain_dkg import DKGChatMessageHistory, DKGMemory, DKGRetriever
from langchain_core.messages import HumanMessage, AIMessage
# Store and retrieve conversation turns
history = DKGChatMessageHistory(context_graph_id="my-project")
history.add_message(HumanMessage(content="What is a Knowledge Asset?"))
history.add_message(AIMessage(content="An ownable container of structured knowledge on the DKG."))
messages = history.messages # tri-modal semantic search
With a LangChain chain (modern LCEL style)
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_dkg import DKGMemory
llm = ChatOpenAI(model="gpt-4o-mini")
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant."),
MessagesPlaceholder(variable_name="history"),
("human", "{input}"),
])
chain_with_memory = DKGMemory.wrap_chain(
prompt | llm,
context_graph_id="my-project",
)
response = chain_with_memory.invoke(
{"input": "What is DKG?"},
config={"configurable": {"session_id": "user-42"}},
)
RAG retrieval via SPARQL
from langchain_dkg import DKGRetriever
from langchain.chains import RetrievalQA
retriever = DKGRetriever(limit=10)
chain = RetrievalQA.from_chain_type(llm=llm, retriever=retriever)
Components
| Class | LangChain base | Purpose |
|---|---|---|
DKGChatMessageHistory |
BaseChatMessageHistory |
Stores turns in DKG WM; retrieves via tri-modal search |
DKGMemory |
— | Factory for RunnableWithMessageHistory with DKG backend |
DKGRetriever |
BaseRetriever |
SPARQL retriever — returns triples as Document objects |
DKGClient |
— | Low-level async HTTP client for the DKG v10 API |
Memory layers
DKG v10 has three memory layers:
| Layer | Scope | Cost | Use |
|---|---|---|---|
Working Memory (wm) |
Private to your node | Free | Default for conversation history |
Shared Working Memory (swm) |
Gossip-replicated | Free | Team-visible context |
| Verified Memory | On-chain, permanent | TRAC | Auditable, publishable knowledge |
Breaking behavior change (0.1.9): turns are now written to private Working Memory (
layer="wm") by default. Earlier versions deferred to the node's default, which is Shared Working Memory (swm, gossiped to peers). Passlayer="swm"to keep the old gossiped behavior, orlayer=Noneto use the node's default.
Explicit promotion to Shared Memory:
turn_uri = history.get_turn_uri("**Human:** Summarize this meeting")
await history.promote_to_shared(turn_uri)
Promotion is asynchronous on current node builds: DKGClient.assertion_promote
submits a job via POST /api/assertion/{name}/promote-async, then polls
GET /api/assertion/promote-async/{jobId} (about once per second, up to
poll_timeout=30.0 seconds) and returns the final job view. A failed job
raises CuratorUnconfirmedError / CuratorRejectedError when the curator did
not confirm or rejected the write, and DKGError otherwise (including poll
timeouts). Note: current node builds expose promotion for named Working Memory
assertions; promoting memory turns by URI may not be supported.
Retrieval options
History retrieval is semantic-relevance based — history.messages runs a
tri-modal search seeded by search_query, not a chronological dump.
search_query(DKGChatMessageHistory,DKGMemory): seed query used to retrieve relevant past turns. Defaults to"conversation history"; set it to the session's topic for sharper retrieval.search_layers(DKGChatMessageHistory): memory layers searched, default["wm", "swm"]. Current node builds return nothing whenmemoryLayersis omitted, so the layers are always sent explicitly.context_graph_id(DKGRetriever): scopes SPARQL queries to a Context Graph — required by current node builds to see workspace (Working Memory) data.
Configuration
| Env var | Default | Description |
|---|---|---|
DKG_TOKEN |
— | Bearer token from dkg auth show |
DKG_BASE_URL |
http://localhost:9200 |
DKG node API URL |
Or pass token= / base_url= directly to DKGClient.
Session isolation
Each session_id passed to chain_with_memory.invoke(config={"configurable": {"session_id": "..."}}) becomes a sessionUri in DKG, linking turns together within the shared Context Graph.
When session_uri is set on DKGChatMessageHistory, retrieval applies a
client-side session filter: the node's search API has no session parameter, so
the history over-fetches, looks up the session's turns via SPARQL
(<session_uri> <http://schema.org/hasPart> ?turn), keeps only those turns
and sorts them chronologically. If the lookup fails or the session has no
linked turns, unfiltered search results are returned.
Node compatibility
DKG v10 nodes auto-update, and pre-release API surfaces drift (e.g. the
synchronous promote route was replaced by promote-async, memory/search
began requiring memoryLayers, and /api/query changed its result shape).
This version was verified against node build 10.0.2 (July 2026). If you see
unexpected 404s/400s or empty results after a node update, check for a newer
langchain-dkg release.
Known limitations of node 10.0.2:
/api/querycannot see Working Memory (wm) quads. The RFC-29 working-memory isolation gate is fail-closed and the signature plumbing is not shipped in this build, so SPARQL queries (includingDKGRetriever) only cover Shared Working Memory and published data —include_workspace=Truemaps to the node'sincludeSharedMemory. Usehistory.messages/memory_search(which does returnwmresults) to retrieve private turns, or write turns withlayer="swm"when they must be SPARQL-queryable.- The legacy
/api/assertion/createand promote routes moved to the/api/knowledge-assetssurface; this client targets the new routes and falls back to the legacy ones on 404.assertion_write/assertion_history/shared_memory_publishstill target legacy routes that 404 on10.0.2(the new equivalents are/api/knowledge-assets/{name}/wm/writeand the publish surface); they will be ported in a future release.
Development
pip install -e ".[dev]"
pytest tests/unit/ # unit tests (no node required)
DKG_TOKEN=$(dkg auth show) pytest tests/integration/ # integration tests
python examples/research_agent.py # demo script
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file langchain_dkg-0.1.9.tar.gz.
File metadata
- Download URL: langchain_dkg-0.1.9.tar.gz
- Upload date:
- Size: 41.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8db504c969777ab8dc562713d3a585b7cff37f5a03aa855a6e33fc3709de0bfe
|
|
| MD5 |
8d0a4d915f0c04be285fd4574efbd03c
|
|
| BLAKE2b-256 |
f1da300d5a7b64a1b5375a2f04ef16106c7e93eab67d2b7d4042dbde89a5bd33
|
Provenance
The following attestation bundles were made for langchain_dkg-0.1.9.tar.gz:
Publisher:
publish.yml on haroldboom/dkg-langchain
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
langchain_dkg-0.1.9.tar.gz -
Subject digest:
8db504c969777ab8dc562713d3a585b7cff37f5a03aa855a6e33fc3709de0bfe - Sigstore transparency entry: 2064618829
- Sigstore integration time:
-
Permalink:
haroldboom/dkg-langchain@70196226d49cc4c253236817acd10f3bce574193 -
Branch / Tag:
refs/tags/v0.1.9 - Owner: https://github.com/haroldboom
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@70196226d49cc4c253236817acd10f3bce574193 -
Trigger Event:
push
-
Statement type:
File details
Details for the file langchain_dkg-0.1.9-py3-none-any.whl.
File metadata
- Download URL: langchain_dkg-0.1.9-py3-none-any.whl
- Upload date:
- Size: 21.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
87583cfea3b9a513e0cd8f4f69d58198257e9dbbacd19423a13313db3b0bbee4
|
|
| MD5 |
8b87ffbf918db983fea41c41cada3245
|
|
| BLAKE2b-256 |
334af5570cc47042f278e06ae60cb0fa1f5036f3c2291e58c9872b2ba3f32ee9
|
Provenance
The following attestation bundles were made for langchain_dkg-0.1.9-py3-none-any.whl:
Publisher:
publish.yml on haroldboom/dkg-langchain
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
langchain_dkg-0.1.9-py3-none-any.whl -
Subject digest:
87583cfea3b9a513e0cd8f4f69d58198257e9dbbacd19423a13313db3b0bbee4 - Sigstore transparency entry: 2064618865
- Sigstore integration time:
-
Permalink:
haroldboom/dkg-langchain@70196226d49cc4c253236817acd10f3bce574193 -
Branch / Tag:
refs/tags/v0.1.9 - Owner: https://github.com/haroldboom
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@70196226d49cc4c253236817acd10f3bce574193 -
Trigger Event:
push
-
Statement type: