@aeriondyseti/vector-memory-mcp 1.0.2-dev.0 → 1.1.0-dev.2
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/dist/package.json +4 -4
- package/dist/src/config/index.d.ts +10 -0
- package/dist/src/config/index.d.ts.map +1 -1
- package/dist/src/config/index.js +13 -0
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/db/conversation-history.repository.d.ts +24 -0
- package/dist/src/db/conversation-history.repository.d.ts.map +1 -0
- package/dist/src/db/conversation-history.repository.js +184 -0
- package/dist/src/db/conversation-history.repository.js.map +1 -0
- package/dist/src/db/conversation-history.schema.d.ts +10 -0
- package/dist/src/db/conversation-history.schema.d.ts.map +1 -0
- package/dist/src/db/conversation-history.schema.js +31 -0
- package/dist/src/db/conversation-history.schema.js.map +1 -0
- package/dist/src/db/lancedb-utils.d.ts +35 -0
- package/dist/src/db/lancedb-utils.d.ts.map +1 -0
- package/dist/src/db/lancedb-utils.js +77 -0
- package/dist/src/db/lancedb-utils.js.map +1 -0
- package/dist/src/db/memory.repository.d.ts +2 -12
- package/dist/src/db/memory.repository.d.ts.map +1 -1
- package/dist/src/db/memory.repository.js +13 -56
- package/dist/src/db/memory.repository.js.map +1 -1
- package/dist/src/db/schema.d.ts +4 -1
- package/dist/src/db/schema.d.ts.map +1 -1
- package/dist/src/db/schema.js +8 -4
- package/dist/src/db/schema.js.map +1 -1
- package/dist/src/index.js +8 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/handlers.d.ts +3 -0
- package/dist/src/mcp/handlers.d.ts.map +1 -1
- package/dist/src/mcp/handlers.js +149 -17
- package/dist/src/mcp/handlers.js.map +1 -1
- package/dist/src/mcp/tools.d.ts +3 -0
- package/dist/src/mcp/tools.d.ts.map +1 -1
- package/dist/src/mcp/tools.js +54 -3
- package/dist/src/mcp/tools.js.map +1 -1
- package/dist/src/services/conversation-history.service.d.ts +64 -0
- package/dist/src/services/conversation-history.service.d.ts.map +1 -0
- package/dist/src/services/conversation-history.service.js +244 -0
- package/dist/src/services/conversation-history.service.js.map +1 -0
- package/dist/src/services/memory.service.d.ts +24 -0
- package/dist/src/services/memory.service.d.ts.map +1 -1
- package/dist/src/services/memory.service.js +58 -0
- package/dist/src/services/memory.service.js.map +1 -1
- package/dist/src/services/session-parser.d.ts +59 -0
- package/dist/src/services/session-parser.d.ts.map +1 -0
- package/dist/src/services/session-parser.js +147 -0
- package/dist/src/services/session-parser.js.map +1 -0
- package/dist/src/types/conversation-history.d.ts +74 -0
- package/dist/src/types/conversation-history.d.ts.map +1 -0
- package/dist/src/types/conversation-history.js +2 -0
- package/dist/src/types/conversation-history.js.map +1 -0
- package/dist/src/types/memory.d.ts +4 -2
- package/dist/src/types/memory.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/config/index.ts +23 -0
- package/src/db/conversation-history.repository.ts +255 -0
- package/src/db/conversation-history.schema.ts +40 -0
- package/src/db/lancedb-utils.ts +97 -0
- package/src/db/memory.repository.ts +18 -67
- package/src/db/schema.ts +17 -21
- package/src/index.ts +16 -0
- package/src/mcp/handlers.ts +178 -22
- package/src/mcp/tools.ts +66 -3
- package/src/services/conversation-history.service.ts +320 -0
- package/src/services/memory.service.ts +74 -0
- package/src/services/session-parser.ts +232 -0
- package/src/types/conversation-history.ts +82 -0
- package/src/types/memory.ts +4 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/mcp/tools.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,iBAAiB,GAAS;IACrC,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;kFAqBmE;IAChF,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,QAAQ,EAAE;gBACR,IAAI,EAAE,OAAO;gBACb,WAAW,EAAE,oBAAoB;gBACjC,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,OAAO,EAAE;4BACP,IAAI,EAAE,QAAQ;4BACd,WAAW,EAAE,uBAAuB;yBACrC;wBACD,cAAc,EAAE;4BACd,IAAI,EAAE,QAAQ;4BACd,WAAW,EACT,iEAAiE;yBACpE;wBACD,QAAQ,EAAE;4BACR,IAAI,EAAE,QAAQ;4BACd,WAAW,EAAE,8BAA8B;4BAC3C,oBAAoB,EAAE,IAAI;yBAC3B;qBACF;oBACD,QAAQ,EAAE,CAAC,SAAS,CAAC;iBACtB;aACF;SACF;QACD,QAAQ,EAAE,CAAC,UAAU,CAAC;KACvB;CACF,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/mcp/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { ConversationHistoryRepository } from "../db/conversation-history.repository.js";
|
|
2
|
+
import type { EmbeddingsService } from "./embeddings.service.js";
|
|
3
|
+
import type { HistorySearchResult, IndexedSessionSummary, IndexingSummary } from "../types/conversation-history.js";
|
|
4
|
+
export declare class ConversationHistoryService {
|
|
5
|
+
private repository;
|
|
6
|
+
private embeddings;
|
|
7
|
+
private sessionPath;
|
|
8
|
+
constructor(repository: ConversationHistoryRepository, embeddings: EmbeddingsService, sessionPath: string | null);
|
|
9
|
+
/**
|
|
10
|
+
* Index all conversation sessions found in the session directory.
|
|
11
|
+
*
|
|
12
|
+
* For each .jsonl file discovered:
|
|
13
|
+
* - New (not tracked): full parse from byte 0
|
|
14
|
+
* - Grown (fileSize increased): incremental parse from last-known size
|
|
15
|
+
* - Shrunk (fileSize decreased — file replaced): delete + full reindex
|
|
16
|
+
* - Unchanged (same fileSize): skip
|
|
17
|
+
*/
|
|
18
|
+
indexConversations(sessionDir?: string): Promise<IndexingSummary>;
|
|
19
|
+
/**
|
|
20
|
+
* Search conversation history using hybrid (vector + FTS) search.
|
|
21
|
+
*/
|
|
22
|
+
search(query: string, limit: number): Promise<HistorySearchResult[]>;
|
|
23
|
+
/**
|
|
24
|
+
* List all indexed sessions (pass-through to repository).
|
|
25
|
+
*/
|
|
26
|
+
listIndexedSessions(): Promise<IndexedSessionSummary[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Force a full reindex of a specific session.
|
|
29
|
+
* Deletes all existing entries and tracking, then re-parses from byte 0.
|
|
30
|
+
*/
|
|
31
|
+
reindexSession(sessionId: string): Promise<IndexingSummary>;
|
|
32
|
+
/**
|
|
33
|
+
* Bulk-fetch all tracked sessions into a Map for O(1) lookups.
|
|
34
|
+
* Uses listIndexedSessions() which returns summaries, but we need full
|
|
35
|
+
* IndexedSession records. We call getIndexedSession() is avoided by using
|
|
36
|
+
* a repository method that returns all sessions with full details.
|
|
37
|
+
*
|
|
38
|
+
* Note: listIndexedSessions returns IndexedSessionSummary (no filePath/fileSize),
|
|
39
|
+
* so we use getIndexedSession per unique session. However, we batch this via
|
|
40
|
+
* the list + individual fetches only when needed. For now, we fetch all as
|
|
41
|
+
* summaries and promote to full records via individual lookups grouped upfront.
|
|
42
|
+
*/
|
|
43
|
+
private buildSessionIndex;
|
|
44
|
+
/**
|
|
45
|
+
* Discover all .jsonl files across resolved session directories.
|
|
46
|
+
* Resolves dirs and discovers files in one pass to avoid double-scanning.
|
|
47
|
+
*/
|
|
48
|
+
private discoverAllFiles;
|
|
49
|
+
/**
|
|
50
|
+
* List immediate subdirectories of a path. Stat calls are parallelized.
|
|
51
|
+
*/
|
|
52
|
+
private listSubdirectories;
|
|
53
|
+
/**
|
|
54
|
+
* Parse a session file, embed messages in batches, insert into repository,
|
|
55
|
+
* and upsert the tracking record. Returns count of messages indexed.
|
|
56
|
+
*/
|
|
57
|
+
private indexFile;
|
|
58
|
+
/**
|
|
59
|
+
* Upsert the indexed session tracking record.
|
|
60
|
+
* For incremental indexing, merges timestamps with the existing record.
|
|
61
|
+
*/
|
|
62
|
+
private upsertTracking;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=conversation-history.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-history.service.d.ts","sourceRoot":"","sources":["../../../src/services/conversation-history.service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,0CAA0C,CAAC;AAC9F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AASjE,OAAO,KAAK,EAEV,mBAAmB,EAEnB,qBAAqB,EACrB,eAAe,EAChB,MAAM,kCAAkC,CAAC;AAI1C,qBAAa,0BAA0B;IAEnC,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,WAAW;gBAFX,UAAU,EAAE,6BAA6B,EACzC,UAAU,EAAE,iBAAiB,EAC7B,WAAW,EAAE,MAAM,GAAG,IAAI;IAGpC;;;;;;;;OAQG;IACG,kBAAkB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAsDvE;;OAEG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAiB1E;;OAEG;IACG,mBAAmB,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAI7D;;;OAGG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IA6CjE;;;;;;;;;;OAUG;YACW,iBAAiB;IAkB/B;;;OAGG;YACW,gBAAgB;IAc9B;;OAEG;YACW,kBAAkB;IAsBhC;;;OAGG;YACW,SAAS;IA4CvB;;;OAGG;YACW,cAAc;CA2B7B"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { readdir, stat } from "fs/promises";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { parseSessionFile, discoverSessionFiles, detectSessionPath, } from "./session-parser.js";
|
|
4
|
+
const EMBED_BATCH_SIZE = 50;
|
|
5
|
+
export class ConversationHistoryService {
|
|
6
|
+
repository;
|
|
7
|
+
embeddings;
|
|
8
|
+
sessionPath;
|
|
9
|
+
constructor(repository, embeddings, sessionPath) {
|
|
10
|
+
this.repository = repository;
|
|
11
|
+
this.embeddings = embeddings;
|
|
12
|
+
this.sessionPath = sessionPath;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Index all conversation sessions found in the session directory.
|
|
16
|
+
*
|
|
17
|
+
* For each .jsonl file discovered:
|
|
18
|
+
* - New (not tracked): full parse from byte 0
|
|
19
|
+
* - Grown (fileSize increased): incremental parse from last-known size
|
|
20
|
+
* - Shrunk (fileSize decreased — file replaced): delete + full reindex
|
|
21
|
+
* - Unchanged (same fileSize): skip
|
|
22
|
+
*/
|
|
23
|
+
async indexConversations(sessionDir) {
|
|
24
|
+
const allFiles = await this.discoverAllFiles(sessionDir);
|
|
25
|
+
// Bulk-fetch all tracked sessions into a Map to avoid N+1 lookups
|
|
26
|
+
const trackedSessions = await this.buildSessionIndex();
|
|
27
|
+
const summary = {
|
|
28
|
+
sessionsDiscovered: allFiles.length,
|
|
29
|
+
sessionsIndexed: 0,
|
|
30
|
+
sessionsSkipped: 0,
|
|
31
|
+
messagesIndexed: 0,
|
|
32
|
+
};
|
|
33
|
+
for (const file of allFiles) {
|
|
34
|
+
const indexed = trackedSessions.get(file.sessionId) ?? null;
|
|
35
|
+
if (indexed && indexed.fileSize === file.fileSize) {
|
|
36
|
+
// Unchanged — skip
|
|
37
|
+
summary.sessionsSkipped++;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (indexed && file.fileSize < indexed.fileSize) {
|
|
41
|
+
// Shrunk — file was replaced, full reindex
|
|
42
|
+
await this.repository.deleteBySessionId(file.sessionId);
|
|
43
|
+
await this.repository.deleteIndexedSession(file.sessionId);
|
|
44
|
+
const count = await this.indexFile(file, 0, 0, null);
|
|
45
|
+
summary.sessionsIndexed++;
|
|
46
|
+
summary.messagesIndexed += count;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (indexed && file.fileSize > indexed.fileSize) {
|
|
50
|
+
// Grown — incremental parse from where we left off
|
|
51
|
+
const count = await this.indexFile(file, indexed.fileSize, indexed.messageCount, indexed);
|
|
52
|
+
summary.sessionsIndexed++;
|
|
53
|
+
summary.messagesIndexed += count;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
// New — full parse
|
|
57
|
+
const count = await this.indexFile(file, 0, 0, null);
|
|
58
|
+
summary.sessionsIndexed++;
|
|
59
|
+
summary.messagesIndexed += count;
|
|
60
|
+
}
|
|
61
|
+
return summary;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Search conversation history using hybrid (vector + FTS) search.
|
|
65
|
+
*/
|
|
66
|
+
async search(query, limit) {
|
|
67
|
+
const embedding = await this.embeddings.embed(query);
|
|
68
|
+
const rows = await this.repository.findHybrid(embedding, query, limit);
|
|
69
|
+
return rows.map((row) => ({
|
|
70
|
+
source: "conversation_history",
|
|
71
|
+
id: row.id,
|
|
72
|
+
content: row.content,
|
|
73
|
+
metadata: row.metadata,
|
|
74
|
+
score: row.rrfScore,
|
|
75
|
+
sessionId: row.sessionId,
|
|
76
|
+
role: row.role,
|
|
77
|
+
messageIndex: row.messageIndex,
|
|
78
|
+
timestamp: row.timestamp,
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* List all indexed sessions (pass-through to repository).
|
|
83
|
+
*/
|
|
84
|
+
async listIndexedSessions() {
|
|
85
|
+
return this.repository.listIndexedSessions();
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Force a full reindex of a specific session.
|
|
89
|
+
* Deletes all existing entries and tracking, then re-parses from byte 0.
|
|
90
|
+
*/
|
|
91
|
+
async reindexSession(sessionId) {
|
|
92
|
+
const indexed = await this.repository.getIndexedSession(sessionId);
|
|
93
|
+
const summary = {
|
|
94
|
+
sessionsDiscovered: 1,
|
|
95
|
+
sessionsIndexed: 0,
|
|
96
|
+
sessionsSkipped: 0,
|
|
97
|
+
messagesIndexed: 0,
|
|
98
|
+
};
|
|
99
|
+
if (!indexed) {
|
|
100
|
+
// Nothing to reindex — no tracking record means we don't know the file path
|
|
101
|
+
summary.sessionsSkipped = 1;
|
|
102
|
+
return summary;
|
|
103
|
+
}
|
|
104
|
+
// Delete existing data
|
|
105
|
+
await this.repository.deleteBySessionId(sessionId);
|
|
106
|
+
await this.repository.deleteIndexedSession(sessionId);
|
|
107
|
+
// Get current file size (file may have changed since last index)
|
|
108
|
+
let fileSize;
|
|
109
|
+
try {
|
|
110
|
+
const stats = await stat(indexed.filePath);
|
|
111
|
+
fileSize = stats.size;
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// File no longer exists
|
|
115
|
+
summary.sessionsSkipped = 1;
|
|
116
|
+
return summary;
|
|
117
|
+
}
|
|
118
|
+
const fileInfo = {
|
|
119
|
+
sessionId,
|
|
120
|
+
filePath: indexed.filePath,
|
|
121
|
+
fileSize,
|
|
122
|
+
};
|
|
123
|
+
const count = await this.indexFile(fileInfo, 0, 0, null);
|
|
124
|
+
summary.sessionsIndexed = 1;
|
|
125
|
+
summary.messagesIndexed = count;
|
|
126
|
+
return summary;
|
|
127
|
+
}
|
|
128
|
+
// --- Private helpers ---
|
|
129
|
+
/**
|
|
130
|
+
* Bulk-fetch all tracked sessions into a Map for O(1) lookups.
|
|
131
|
+
* Uses listIndexedSessions() which returns summaries, but we need full
|
|
132
|
+
* IndexedSession records. We call getIndexedSession() is avoided by using
|
|
133
|
+
* a repository method that returns all sessions with full details.
|
|
134
|
+
*
|
|
135
|
+
* Note: listIndexedSessions returns IndexedSessionSummary (no filePath/fileSize),
|
|
136
|
+
* so we use getIndexedSession per unique session. However, we batch this via
|
|
137
|
+
* the list + individual fetches only when needed. For now, we fetch all as
|
|
138
|
+
* summaries and promote to full records via individual lookups grouped upfront.
|
|
139
|
+
*/
|
|
140
|
+
async buildSessionIndex() {
|
|
141
|
+
const summaries = await this.repository.listIndexedSessions();
|
|
142
|
+
const sessionMap = new Map();
|
|
143
|
+
// Fetch full records in parallel for all known sessions
|
|
144
|
+
const fullRecords = await Promise.all(summaries.map((s) => this.repository.getIndexedSession(s.sessionId)));
|
|
145
|
+
for (const record of fullRecords) {
|
|
146
|
+
if (record) {
|
|
147
|
+
sessionMap.set(record.sessionId, record);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return sessionMap;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Discover all .jsonl files across resolved session directories.
|
|
154
|
+
* Resolves dirs and discovers files in one pass to avoid double-scanning.
|
|
155
|
+
*/
|
|
156
|
+
async discoverAllFiles(sessionDir) {
|
|
157
|
+
const base = sessionDir ?? this.sessionPath ?? detectSessionPath();
|
|
158
|
+
if (!base)
|
|
159
|
+
return [];
|
|
160
|
+
// Check if base dir itself has .jsonl files
|
|
161
|
+
const rootFiles = await discoverSessionFiles(base);
|
|
162
|
+
if (rootFiles.length > 0)
|
|
163
|
+
return rootFiles;
|
|
164
|
+
// Otherwise enumerate subdirectories and discover files in each
|
|
165
|
+
const dirs = await this.listSubdirectories(base);
|
|
166
|
+
const nested = await Promise.all(dirs.map((d) => discoverSessionFiles(d)));
|
|
167
|
+
return nested.flat();
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* List immediate subdirectories of a path. Stat calls are parallelized.
|
|
171
|
+
*/
|
|
172
|
+
async listSubdirectories(base) {
|
|
173
|
+
let entries;
|
|
174
|
+
try {
|
|
175
|
+
entries = await readdir(base);
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
return [];
|
|
179
|
+
}
|
|
180
|
+
const results = await Promise.allSettled(entries.map(async (entry) => {
|
|
181
|
+
const fullPath = join(base, entry);
|
|
182
|
+
const stats = await stat(fullPath);
|
|
183
|
+
return stats.isDirectory() ? fullPath : null;
|
|
184
|
+
}));
|
|
185
|
+
return results
|
|
186
|
+
.filter((r) => r.status === "fulfilled")
|
|
187
|
+
.map((r) => r.value)
|
|
188
|
+
.filter((v) => v != null);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Parse a session file, embed messages in batches, insert into repository,
|
|
192
|
+
* and upsert the tracking record. Returns count of messages indexed.
|
|
193
|
+
*/
|
|
194
|
+
async indexFile(file, fromByte, startIndex, existing) {
|
|
195
|
+
const parseResult = await parseSessionFile(file.filePath, fromByte, startIndex, file.fileSize);
|
|
196
|
+
if (parseResult.messages.length === 0) {
|
|
197
|
+
// Still upsert tracking so we don't re-parse an empty/no-new-content file
|
|
198
|
+
await this.upsertTracking(file, parseResult.messages, startIndex, parseResult, existing);
|
|
199
|
+
return 0;
|
|
200
|
+
}
|
|
201
|
+
// Embed and insert in batches
|
|
202
|
+
for (let i = 0; i < parseResult.messages.length; i += EMBED_BATCH_SIZE) {
|
|
203
|
+
const batch = parseResult.messages.slice(i, i + EMBED_BATCH_SIZE);
|
|
204
|
+
const texts = batch.map((m) => m.content);
|
|
205
|
+
const embeddings = await this.embeddings.embedBatch(texts);
|
|
206
|
+
const entries = batch.map((msg, idx) => ({
|
|
207
|
+
id: msg.id,
|
|
208
|
+
content: msg.content,
|
|
209
|
+
embedding: embeddings[idx],
|
|
210
|
+
sessionId: msg.sessionId,
|
|
211
|
+
role: msg.role,
|
|
212
|
+
messageIndex: msg.messageIndex,
|
|
213
|
+
timestamp: msg.timestamp,
|
|
214
|
+
metadata: msg.metadata,
|
|
215
|
+
createdAt: new Date(),
|
|
216
|
+
}));
|
|
217
|
+
await this.repository.insert(entries);
|
|
218
|
+
}
|
|
219
|
+
await this.upsertTracking(file, parseResult.messages, startIndex, parseResult, existing);
|
|
220
|
+
return parseResult.messages.length;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Upsert the indexed session tracking record.
|
|
224
|
+
* For incremental indexing, merges timestamps with the existing record.
|
|
225
|
+
*/
|
|
226
|
+
async upsertTracking(file, newMessages, startIndex, parseResult, existing) {
|
|
227
|
+
const totalMessageCount = startIndex + newMessages.length;
|
|
228
|
+
const firstMessageAt = existing?.firstMessageAt ?? parseResult.firstMessageAt ?? new Date();
|
|
229
|
+
const lastMessageAt = parseResult.lastMessageAt ?? existing?.lastMessageAt ?? new Date();
|
|
230
|
+
const session = {
|
|
231
|
+
sessionId: file.sessionId,
|
|
232
|
+
filePath: file.filePath,
|
|
233
|
+
fileSize: file.fileSize,
|
|
234
|
+
messageCount: totalMessageCount,
|
|
235
|
+
firstMessageAt,
|
|
236
|
+
lastMessageAt,
|
|
237
|
+
indexedAt: new Date(),
|
|
238
|
+
...(parseResult.project ? { project: parseResult.project } : existing?.project ? { project: existing.project } : {}),
|
|
239
|
+
...(parseResult.gitBranch ? { gitBranch: parseResult.gitBranch } : existing?.gitBranch ? { gitBranch: existing.gitBranch } : {}),
|
|
240
|
+
};
|
|
241
|
+
await this.repository.upsertIndexedSession(session);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=conversation-history.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-history.service.js","sourceRoot":"","sources":["../../../src/services/conversation-history.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
import type { Memory, SearchIntent } from "../types/memory.js";
|
|
2
2
|
import type { MemoryRepository } from "../db/memory.repository.js";
|
|
3
3
|
import type { EmbeddingsService } from "./embeddings.service.js";
|
|
4
|
+
import type { ConversationHistoryService } from "./conversation-history.service.js";
|
|
5
|
+
import type { SearchResult } from "../types/conversation-history.js";
|
|
4
6
|
export declare class MemoryService {
|
|
5
7
|
private repository;
|
|
6
8
|
private embeddings;
|
|
9
|
+
private historyService;
|
|
10
|
+
private historyWeight;
|
|
7
11
|
constructor(repository: MemoryRepository, embeddings: EmbeddingsService);
|
|
12
|
+
/**
|
|
13
|
+
* Optionally wire conversation history for unified search.
|
|
14
|
+
* Called from index.ts when conversationHistory.enabled is true.
|
|
15
|
+
*/
|
|
16
|
+
setConversationHistory(service: ConversationHistoryService, weight: number): void;
|
|
17
|
+
/**
|
|
18
|
+
* Access the conversation history service (if wired).
|
|
19
|
+
* Used by MCP handlers for index/list/reindex tools.
|
|
20
|
+
*/
|
|
21
|
+
getConversationHistory(): ConversationHistoryService | null;
|
|
8
22
|
store(content: string, metadata?: Record<string, unknown>, embeddingText?: string): Promise<Memory>;
|
|
9
23
|
get(id: string): Promise<Memory | null>;
|
|
10
24
|
delete(id: string): Promise<boolean>;
|
|
@@ -15,6 +29,16 @@ export declare class MemoryService {
|
|
|
15
29
|
}): Promise<Memory | null>;
|
|
16
30
|
vote(id: string, value: number): Promise<Memory | null>;
|
|
17
31
|
search(query: string, intent: SearchIntent, limit?: number, includeDeleted?: boolean): Promise<Memory[]>;
|
|
32
|
+
/**
|
|
33
|
+
* Search across both memories and conversation history (if enabled).
|
|
34
|
+
* Returns a merged, score-normalized list sorted by relevance.
|
|
35
|
+
*
|
|
36
|
+
* If no history service is configured, falls back to memory-only search
|
|
37
|
+
* wrapped as MemorySearchResult[].
|
|
38
|
+
*/
|
|
39
|
+
searchUnified(query: string, intent: SearchIntent, limit?: number, includeDeleted?: boolean): Promise<SearchResult[]>;
|
|
40
|
+
/** Convert pre-sorted Memory[] to MemorySearchResult[] with positional scores. */
|
|
41
|
+
private toMemoryResults;
|
|
18
42
|
trackAccess(ids: string[]): Promise<void>;
|
|
19
43
|
private static readonly UUID_ZERO;
|
|
20
44
|
storeCheckpoint(args: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.service.d.ts","sourceRoot":"","sources":["../../../src/services/memory.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAiB,MAAM,oBAAoB,CAAC;AAE9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"memory.service.d.ts","sourceRoot":"","sources":["../../../src/services/memory.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAiB,MAAM,oBAAoB,CAAC;AAE9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AACpF,OAAO,KAAK,EAAE,YAAY,EAAsB,MAAM,kCAAkC,CAAC;AAYzF,qBAAa,aAAa;IAKtB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,UAAU;IALpB,OAAO,CAAC,cAAc,CAA2C;IACjE,OAAO,CAAC,aAAa,CAAe;gBAG1B,UAAU,EAAE,gBAAgB,EAC5B,UAAU,EAAE,iBAAiB;IAGvC;;;OAGG;IACH,sBAAsB,CAAC,OAAO,EAAE,0BAA0B,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAKjF;;;OAGG;IACH,sBAAsB,IAAI,0BAA0B,GAAG,IAAI;IAIrD,KAAK,CACT,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACtC,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC;IAuBZ,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAiBvC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIpC,MAAM,CACV,EAAE,EAAE,MAAM,EACV,OAAO,EAAE;QACP,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,GACA,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA4BnB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAmBvD,MAAM,CACV,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,YAAY,EACpB,KAAK,GAAE,MAAW,EAClB,cAAc,GAAE,OAAe,GAC9B,OAAO,CAAC,MAAM,EAAE,CAAC;IA0CpB;;;;;;OAMG;IACG,aAAa,CACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,YAAY,EACpB,KAAK,GAAE,MAAW,EAClB,cAAc,GAAE,OAAe,GAC9B,OAAO,CAAC,YAAY,EAAE,CAAC;IA0B1B,kFAAkF;IAClF,OAAO,CAAC,eAAe;IAajB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAc/C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CACQ;IAEnC,eAAe,CAAC,IAAI,EAAE;QAC1B,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC/B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,GAAG,OAAO,CAAC,MAAM,CAAC;IAgEb,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAGpD"}
|
|
@@ -11,10 +11,27 @@ const sigmoid = (x) => 1 / (1 + Math.exp(-x));
|
|
|
11
11
|
export class MemoryService {
|
|
12
12
|
repository;
|
|
13
13
|
embeddings;
|
|
14
|
+
historyService = null;
|
|
15
|
+
historyWeight = 0.5;
|
|
14
16
|
constructor(repository, embeddings) {
|
|
15
17
|
this.repository = repository;
|
|
16
18
|
this.embeddings = embeddings;
|
|
17
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Optionally wire conversation history for unified search.
|
|
22
|
+
* Called from index.ts when conversationHistory.enabled is true.
|
|
23
|
+
*/
|
|
24
|
+
setConversationHistory(service, weight) {
|
|
25
|
+
this.historyService = service;
|
|
26
|
+
this.historyWeight = weight;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Access the conversation history service (if wired).
|
|
30
|
+
* Used by MCP handlers for index/list/reindex tools.
|
|
31
|
+
*/
|
|
32
|
+
getConversationHistory() {
|
|
33
|
+
return this.historyService;
|
|
34
|
+
}
|
|
18
35
|
async store(content, metadata = {}, embeddingText) {
|
|
19
36
|
const id = randomUUID();
|
|
20
37
|
const now = new Date();
|
|
@@ -122,6 +139,47 @@ export class MemoryService {
|
|
|
122
139
|
// Return top N (read-only - no access tracking)
|
|
123
140
|
return scored.slice(0, limit).map((s) => s.memory);
|
|
124
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Search across both memories and conversation history (if enabled).
|
|
144
|
+
* Returns a merged, score-normalized list sorted by relevance.
|
|
145
|
+
*
|
|
146
|
+
* If no history service is configured, falls back to memory-only search
|
|
147
|
+
* wrapped as MemorySearchResult[].
|
|
148
|
+
*/
|
|
149
|
+
async searchUnified(query, intent, limit = 10, includeDeleted = false) {
|
|
150
|
+
if (!this.historyService) {
|
|
151
|
+
const memories = await this.search(query, intent, limit, includeDeleted);
|
|
152
|
+
return this.toMemoryResults(memories, limit);
|
|
153
|
+
}
|
|
154
|
+
// Run both searches in parallel
|
|
155
|
+
const [memories, historyResults] = await Promise.all([
|
|
156
|
+
this.search(query, intent, limit, includeDeleted),
|
|
157
|
+
this.historyService.search(query, limit),
|
|
158
|
+
]);
|
|
159
|
+
const memoryResults = this.toMemoryResults(memories, limit);
|
|
160
|
+
// Apply history weight to RRF scores
|
|
161
|
+
const weightedHistory = historyResults.map((h) => ({
|
|
162
|
+
...h,
|
|
163
|
+
score: h.score * this.historyWeight,
|
|
164
|
+
}));
|
|
165
|
+
// Merge, sort by score descending, take top N
|
|
166
|
+
const merged = [...memoryResults, ...weightedHistory];
|
|
167
|
+
merged.sort((a, b) => b.score - a.score);
|
|
168
|
+
return merged.slice(0, limit);
|
|
169
|
+
}
|
|
170
|
+
/** Convert pre-sorted Memory[] to MemorySearchResult[] with positional scores. */
|
|
171
|
+
toMemoryResults(memories, limit) {
|
|
172
|
+
return memories.map((m, rank) => ({
|
|
173
|
+
source: "memory",
|
|
174
|
+
id: m.id,
|
|
175
|
+
content: m.content,
|
|
176
|
+
metadata: m.metadata,
|
|
177
|
+
score: (limit - rank) / limit,
|
|
178
|
+
createdAt: m.createdAt,
|
|
179
|
+
updatedAt: m.updatedAt,
|
|
180
|
+
supersededBy: m.supersededBy,
|
|
181
|
+
}));
|
|
182
|
+
}
|
|
125
183
|
async trackAccess(ids) {
|
|
126
184
|
const now = new Date();
|
|
127
185
|
for (const id of ids) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.service.js","sourceRoot":"","sources":["../../../src/services/memory.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"memory.service.js","sourceRoot":"","sources":["../../../src/services/memory.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { MessageRole } from "../types/conversation-history.js";
|
|
2
|
+
/**
|
|
3
|
+
* A parsed message extracted from a Claude Code JSONL session file.
|
|
4
|
+
* Does not include embedding — that's added by the service layer.
|
|
5
|
+
*/
|
|
6
|
+
export interface ParsedMessage {
|
|
7
|
+
id: string;
|
|
8
|
+
sessionId: string;
|
|
9
|
+
role: MessageRole;
|
|
10
|
+
messageIndex: number;
|
|
11
|
+
content: string;
|
|
12
|
+
timestamp: Date;
|
|
13
|
+
metadata: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Info about a discovered session file (before parsing).
|
|
17
|
+
*/
|
|
18
|
+
export interface SessionFileInfo {
|
|
19
|
+
sessionId: string;
|
|
20
|
+
filePath: string;
|
|
21
|
+
fileSize: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Result of parsing a single session file.
|
|
25
|
+
* Structurally mirrors IndexedSession but with nullable timestamps/metadata
|
|
26
|
+
* (a file with 0 messages has no timestamps). The service layer maps this to
|
|
27
|
+
* IndexedSession at write time, supplying messageCount and indexedAt.
|
|
28
|
+
*/
|
|
29
|
+
export interface ParseResult {
|
|
30
|
+
sessionId: string;
|
|
31
|
+
filePath: string;
|
|
32
|
+
fileSize: number;
|
|
33
|
+
messages: ParsedMessage[];
|
|
34
|
+
firstMessageAt: Date | null;
|
|
35
|
+
lastMessageAt: Date | null;
|
|
36
|
+
gitBranch: string | null;
|
|
37
|
+
project: string | null;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Parse a single Claude Code JSONL session file.
|
|
41
|
+
*
|
|
42
|
+
* @param filePath - Absolute path to the .jsonl file
|
|
43
|
+
* @param fromByte - Byte offset to start reading from (for incremental parsing).
|
|
44
|
+
* When non-zero, messageIndex starts from startIndex.
|
|
45
|
+
* @param startIndex - Starting message index (for incremental parsing).
|
|
46
|
+
* @param knownFileSize - If already known (e.g. from discoverSessionFiles), avoids a redundant stat().
|
|
47
|
+
*/
|
|
48
|
+
export declare function parseSessionFile(filePath: string, fromByte?: number, startIndex?: number, knownFileSize?: number): Promise<ParseResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Discover all .jsonl session files in a directory.
|
|
51
|
+
* Stat calls are parallelized for efficiency.
|
|
52
|
+
*/
|
|
53
|
+
export declare function discoverSessionFiles(sessionDir: string): Promise<SessionFileInfo[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Auto-detect the Claude Code sessions directory.
|
|
56
|
+
* Returns null if not found.
|
|
57
|
+
*/
|
|
58
|
+
export declare function detectSessionPath(): string | null;
|
|
59
|
+
//# sourceMappingURL=session-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-parser.d.ts","sourceRoot":"","sources":["../../../src/services/session-parser.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAEpE;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,WAAW,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,cAAc,EAAE,IAAI,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,IAAI,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAgDD;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,MAAU,EACpB,UAAU,GAAE,MAAU,EACtB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,WAAW,CAAC,CAyEtB;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,EAAE,CAAC,CA8B5B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAOjD"}
|