memtrails 0.5.1 → 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 +14 -0
- package/README.md +20 -0
- package/dist/integrations/document.d.ts +14 -0
- package/dist/integrations/document.js +19 -0
- package/dist/langchain.d.ts +27 -0
- package/dist/langchain.js +30 -0
- package/package.json +14 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,20 @@ 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
|
+
|
|
17
|
+
## [0.5.2] — 2026-11-05
|
|
18
|
+
|
|
19
|
+
- Examples in Python and Rust, the same four as in TypeScript (a quick start, importing sources, the agent tools,
|
|
20
|
+
consolidation), each run in CI against the real model; every README links them. No change to the libraries.
|
|
21
|
+
|
|
8
22
|
## [0.5.1] — 2026-11-05
|
|
9
23
|
|
|
10
24
|
- Rust: the MCP server and the command line, as in TypeScript and Python — `cargo install memtrails`, then
|
package/README.md
CHANGED
|
@@ -29,6 +29,10 @@ const hits = await memory.search({ query: 'why did the certificate stop renewing
|
|
|
29
29
|
await memory.close();
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
+
More to run in [`examples/`](https://github.com/cmaftuleac/memtrails/blob/main/examples): a quick start, importing mail, Slack, git and notes, the agent tools
|
|
33
|
+
(an MCP server, or JSON Schemas for function calling), and consolidation with a language model. The same four are in
|
|
34
|
+
[Python](https://github.com/cmaftuleac/memtrails/blob/main/python/examples) and [Rust](https://github.com/cmaftuleac/memtrails/blob/main/rust/examples).
|
|
35
|
+
|
|
32
36
|
## Why memtrails
|
|
33
37
|
|
|
34
38
|
- **Searchable at once.** No ingestion pipeline to wait for and no model call per record. Add a mailbox and search it.
|
|
@@ -96,6 +100,22 @@ The memory lives in `~/.memtrails` (`--home` or `MEMTRAILS_HOME` for another). T
|
|
|
96
100
|
call and closes it after five minutes without one (`--idle`), so `add` can run in between; `--read-only` leaves out
|
|
97
101
|
`memory_save`. From code: `serveMcp({ open: () => openMemory({ home }), version })`.
|
|
98
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
|
+
|
|
99
119
|
## Adding data
|
|
100
120
|
|
|
101
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.
|
|
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
|
}
|