memtrails 0.5.2 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,15 @@ versions follow [Semantic Versioning](https://semver.org/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.5.3] — 2026-11-05
9
+
10
+ - LangChain and LlamaIndex retrievers: `memtrails/langchain` (with `@langchain/core` beside it, an optional peer), and
11
+ in Python `memtrails.integrations.langchain` and `memtrails.integrations.llama_index` (`pip install
12
+ memtrails[langchain]` / `[llama-index]`). Each found item becomes the framework's document with the same id, text and
13
+ flat metadata in both languages (`conformance/fixtures/retriever.json`). No TypeScript LlamaIndex adapter: its
14
+ packages are no longer maintained.
15
+ The Rust version is released at the same version, unchanged (LangChain and LlamaIndex are Python and JavaScript).
16
+
8
17
  ## [0.5.2] — 2026-11-05
9
18
 
10
19
  - Examples in Python and Rust, the same four as in TypeScript (a quick start, importing sources, the agent tools,
package/README.md CHANGED
@@ -100,6 +100,22 @@ The memory lives in `~/.memtrails` (`--home` or `MEMTRAILS_HOME` for another). T
100
100
  call and closes it after five minutes without one (`--idle`), so `add` can run in between; `--read-only` leaves out
101
101
  `memory_save`. From code: `serveMcp({ open: () => openMemory({ home }), version })`.
102
102
 
103
+ ## LangChain and LlamaIndex
104
+
105
+ A memory is a LangChain retriever (install `@langchain/core` beside memtrails):
106
+
107
+ ```ts
108
+ import { MemtrailsRetriever } from 'memtrails/langchain';
109
+ const docs = await new MemtrailsRetriever({ memory, search: { limit: 8 } }).invoke('why did renewal stop?');
110
+ ```
111
+
112
+ Each document is a found item: its summary (and the passage that matched) as the text, its id, and flat metadata
113
+ (`id`, `kind`, `title`, `date`, `ts`, `score`, and when it has them `eventAt`/`startAt`/`endAt`, `recordId`, `source`,
114
+ `author`, `url`); `memory.open(id)` gives all of it. `search` takes every search option but the query (`collections`,
115
+ `kinds`, `limit`, `from`, `to`; `limit` counts dated observations and other memories each). In Python, LangChain and
116
+ LlamaIndex both: `memtrails.integrations.langchain` and `memtrails.integrations.llama_index`. (LlamaIndex's TypeScript
117
+ packages are no longer maintained, so there is no TypeScript LlamaIndex adapter.)
118
+
103
119
  ## Adding data
104
120
 
105
121
  A **record** is anything with text. Only `id` and `text` are required.
@@ -0,0 +1,14 @@
1
+ /**
2
+ * A found item as a framework's document (a LangChain `Document`; in Python also a LlamaIndex `TextNode`): its id,
3
+ * the text a model reads, and flat metadata a vector store or a prompt can carry. `memory.open(id)` gives the whole item.
4
+ */
5
+ import type { RecalledItem } from '../core/recall.js';
6
+ export interface RetrievedDocument {
7
+ id: string;
8
+ /** The item's summary, and the passage that matched when that was not its start. */
9
+ text: string;
10
+ /** id, kind, title, date (YYYY-MM-DD of `ts`), ts, score; for an observation eventAt, startAt, endAt; for a record you
11
+ * added recordId, source, author, url. Only the ones it has. */
12
+ metadata: Record<string, string | number>;
13
+ }
14
+ export declare function retrievedDocument(h: RecalledItem): RetrievedDocument;
@@ -0,0 +1,19 @@
1
+ export function retrievedDocument(h) {
2
+ const m = {
3
+ id: h.id,
4
+ kind: h.kind,
5
+ title: h.title,
6
+ date: h.ts > 0 ? new Date(h.ts).toISOString().slice(0, 10) : undefined,
7
+ ts: h.ts,
8
+ score: h.score,
9
+ eventAt: h.eventAt,
10
+ startAt: h.startAt,
11
+ endAt: h.endAt,
12
+ recordId: h.record?.id,
13
+ source: h.record?.source,
14
+ author: h.record?.author,
15
+ url: h.record?.url,
16
+ };
17
+ const metadata = Object.fromEntries(Object.entries(m).filter((e) => e[1] !== undefined && e[1] !== ''));
18
+ return { id: h.id, text: h.match ? `${h.summary} … ${h.match}` : h.summary, metadata };
19
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * A memory as a LangChain retriever (`@langchain/core`, installed beside memtrails):
3
+ *
4
+ * import { MemtrailsRetriever } from 'memtrails/langchain';
5
+ * const retriever = new MemtrailsRetriever({ memory, search: { limit: 8 } });
6
+ * const docs = await retriever.invoke('why did the certificate stop renewing?');
7
+ *
8
+ * Each Document is a found item: its summary (and the passage that matched) as `pageContent`, its id, and flat metadata
9
+ * (integrations/document.ts). `search` is every search option but the query: collections, kinds, limit, from, to.
10
+ */
11
+ import { Document } from '@langchain/core/documents';
12
+ import { BaseRetriever, type BaseRetrieverInput } from '@langchain/core/retrievers';
13
+ import type { RecalledItem, SearchQuery } from './core/recall.js';
14
+ export interface MemtrailsRetrieverInput extends BaseRetrieverInput {
15
+ /** An open memory (openMemory), or anything that searches like one. */
16
+ memory: {
17
+ search(q: SearchQuery): Promise<RecalledItem[]>;
18
+ };
19
+ search?: Omit<SearchQuery, 'query'>;
20
+ }
21
+ export declare class MemtrailsRetriever extends BaseRetriever {
22
+ lc_namespace: string[];
23
+ private readonly memory;
24
+ private readonly search;
25
+ constructor(fields: MemtrailsRetrieverInput);
26
+ _getRelevantDocuments(query: string): Promise<Document[]>;
27
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * A memory as a LangChain retriever (`@langchain/core`, installed beside memtrails):
3
+ *
4
+ * import { MemtrailsRetriever } from 'memtrails/langchain';
5
+ * const retriever = new MemtrailsRetriever({ memory, search: { limit: 8 } });
6
+ * const docs = await retriever.invoke('why did the certificate stop renewing?');
7
+ *
8
+ * Each Document is a found item: its summary (and the passage that matched) as `pageContent`, its id, and flat metadata
9
+ * (integrations/document.ts). `search` is every search option but the query: collections, kinds, limit, from, to.
10
+ */
11
+ import { Document } from '@langchain/core/documents';
12
+ import { BaseRetriever } from '@langchain/core/retrievers';
13
+ import { retrievedDocument } from './integrations/document.js';
14
+ export class MemtrailsRetriever extends BaseRetriever {
15
+ lc_namespace = ['memtrails', 'retrievers'];
16
+ memory;
17
+ search;
18
+ constructor(fields) {
19
+ super(fields);
20
+ this.memory = fields.memory;
21
+ this.search = fields.search ?? {};
22
+ }
23
+ async _getRelevantDocuments(query) {
24
+ const hits = await this.memory.search({ ...this.search, query });
25
+ return hits.map((h) => {
26
+ const d = retrievedDocument(h);
27
+ return new Document({ id: d.id, pageContent: d.text, metadata: d.metadata });
28
+ });
29
+ }
30
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memtrails",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Retrieval and exploration for any text — e-mail, chat, notes, documents, news, commits, conversations. Searchable at once, on your own machine, in any language; optional consolidation into typed knowledge with a language model.",
5
5
  "keywords": [
6
6
  "retrieval",
@@ -41,6 +41,10 @@
41
41
  "types": "./dist/importers/index.d.ts",
42
42
  "import": "./dist/importers/index.js"
43
43
  },
44
+ "./langchain": {
45
+ "types": "./dist/langchain.d.ts",
46
+ "import": "./dist/langchain.js"
47
+ },
44
48
  "./package.json": "./package.json"
45
49
  },
46
50
  "bin": {
@@ -71,6 +75,7 @@
71
75
  "onnxruntime-node": "1.23.2"
72
76
  },
73
77
  "devDependencies": {
78
+ "@langchain/core": "1.3.4",
74
79
  "@modelcontextprotocol/sdk": "1.32.2",
75
80
  "@types/node": "^22.10.0",
76
81
  "esbuild": "^0.25.12",
@@ -80,5 +85,13 @@
80
85
  },
81
86
  "publishConfig": {
82
87
  "access": "public"
88
+ },
89
+ "peerDependencies": {
90
+ "@langchain/core": ">=1.0.0 <2"
91
+ },
92
+ "peerDependenciesMeta": {
93
+ "@langchain/core": {
94
+ "optional": true
95
+ }
83
96
  }
84
97
  }