@aeriondyseti/vector-memory-mcp 1.1.0-dev.2 → 1.1.0-dev.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/dist/package.json +1 -1
- package/dist/src/config/index.d.ts +17 -10
- package/dist/src/config/index.d.ts.map +1 -1
- package/dist/src/config/index.js +25 -11
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/db/conversation.repository.d.ts +26 -0
- package/dist/src/db/conversation.repository.d.ts.map +1 -0
- package/dist/src/db/conversation.repository.js +72 -0
- package/dist/src/db/conversation.repository.js.map +1 -0
- package/dist/src/db/conversation.schema.d.ts +4 -0
- package/dist/src/db/conversation.schema.d.ts.map +1 -0
- package/dist/src/db/conversation.schema.js +15 -0
- package/dist/src/db/conversation.schema.js.map +1 -0
- package/dist/src/db/lancedb-utils.d.ts +13 -3
- package/dist/src/db/lancedb-utils.d.ts.map +1 -1
- package/dist/src/db/lancedb-utils.js +36 -7
- package/dist/src/db/lancedb-utils.js.map +1 -1
- package/dist/src/db/memory.repository.js +7 -7
- package/dist/src/db/memory.repository.js.map +1 -1
- package/dist/src/http/server.d.ts.map +1 -1
- package/dist/src/http/server.js +26 -7
- package/dist/src/http/server.js.map +1 -1
- package/dist/src/index.js +7 -6
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/handlers.d.ts +1 -1
- package/dist/src/mcp/handlers.d.ts.map +1 -1
- package/dist/src/mcp/handlers.js +106 -117
- package/dist/src/mcp/handlers.js.map +1 -1
- package/dist/src/mcp/tools.d.ts.map +1 -1
- package/dist/src/mcp/tools.js +43 -14
- package/dist/src/mcp/tools.js.map +1 -1
- package/dist/src/services/conversation.service.d.ts +38 -0
- package/dist/src/services/conversation.service.d.ts.map +1 -0
- package/dist/src/services/conversation.service.js +252 -0
- package/dist/src/services/conversation.service.js.map +1 -0
- package/dist/src/services/memory.service.d.ts +7 -25
- package/dist/src/services/memory.service.d.ts.map +1 -1
- package/dist/src/services/memory.service.js +66 -80
- package/dist/src/services/memory.service.js.map +1 -1
- package/dist/src/services/parsers/claude-code.parser.d.ts +8 -0
- package/dist/src/services/parsers/claude-code.parser.d.ts.map +1 -0
- package/dist/src/services/parsers/claude-code.parser.js +191 -0
- package/dist/src/services/parsers/claude-code.parser.js.map +1 -0
- package/dist/src/services/parsers/types.d.ts +9 -0
- package/dist/src/services/parsers/types.d.ts.map +1 -0
- package/dist/src/services/parsers/types.js +2 -0
- package/dist/src/services/parsers/types.js.map +1 -0
- package/dist/src/types/conversation.d.ts +99 -0
- package/dist/src/types/conversation.d.ts.map +1 -0
- package/dist/src/types/conversation.js +2 -0
- package/dist/src/types/conversation.js.map +1 -0
- package/hooks/session-start.ts +60 -42
- package/package.json +1 -1
- package/src/config/index.ts +39 -21
- package/src/db/conversation.repository.ts +120 -0
- package/src/db/conversation.schema.ts +33 -0
- package/src/db/lancedb-utils.ts +35 -7
- package/src/db/memory.repository.ts +7 -7
- package/src/http/server.ts +31 -7
- package/src/index.ts +10 -11
- package/src/mcp/handlers.ts +121 -123
- package/src/mcp/tools.ts +44 -15
- package/src/services/conversation.service.ts +354 -0
- package/src/services/memory.service.ts +101 -105
- package/src/services/parsers/claude-code.parser.ts +242 -0
- package/src/services/parsers/types.ts +14 -0
- package/src/types/conversation.ts +108 -0
- package/dist/src/db/conversation-history.repository.d.ts +0 -24
- package/dist/src/db/conversation-history.repository.d.ts.map +0 -1
- package/dist/src/db/conversation-history.repository.js +0 -184
- package/dist/src/db/conversation-history.repository.js.map +0 -1
- package/dist/src/db/conversation-history.schema.d.ts +0 -10
- package/dist/src/db/conversation-history.schema.d.ts.map +0 -1
- package/dist/src/db/conversation-history.schema.js +0 -31
- package/dist/src/db/conversation-history.schema.js.map +0 -1
- package/dist/src/services/conversation-history.service.d.ts +0 -64
- package/dist/src/services/conversation-history.service.d.ts.map +0 -1
- package/dist/src/services/conversation-history.service.js +0 -244
- package/dist/src/services/conversation-history.service.js.map +0 -1
- package/dist/src/services/session-parser.d.ts +0 -59
- package/dist/src/services/session-parser.d.ts.map +0 -1
- package/dist/src/services/session-parser.js +0 -147
- package/dist/src/services/session-parser.js.map +0 -1
- package/dist/src/types/conversation-history.d.ts +0 -74
- package/dist/src/types/conversation-history.d.ts.map +0 -1
- package/dist/src/types/conversation-history.js +0 -2
- package/dist/src/types/conversation-history.js.map +0 -1
- package/src/db/conversation-history.repository.ts +0 -255
- package/src/db/conversation-history.schema.ts +0 -40
- package/src/services/conversation-history.service.ts +0 -320
- package/src/services/session-parser.ts +0 -232
- package/src/types/conversation-history.ts +0 -82
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import * as lancedb from "@lancedb/lancedb";
|
|
2
|
+
import { type Table } from "@lancedb/lancedb";
|
|
3
|
+
import {
|
|
4
|
+
CONVERSATION_TABLE_NAME,
|
|
5
|
+
conversationSchema,
|
|
6
|
+
} from "./conversation.schema.js";
|
|
7
|
+
import type {
|
|
8
|
+
ConversationHybridRow,
|
|
9
|
+
HistoryFilters,
|
|
10
|
+
} from "../types/conversation.js";
|
|
11
|
+
import {
|
|
12
|
+
getOrCreateTable,
|
|
13
|
+
createFtsMutex,
|
|
14
|
+
createRerankerMutex,
|
|
15
|
+
escapeSql,
|
|
16
|
+
safeParseJsonObject,
|
|
17
|
+
} from "./lancedb-utils.js";
|
|
18
|
+
|
|
19
|
+
export class ConversationRepository {
|
|
20
|
+
private tablePromise: Promise<Table> | null = null;
|
|
21
|
+
|
|
22
|
+
// FTS index mutex — recreated after data mutations to force re-check
|
|
23
|
+
private ensureFtsIndex = createFtsMutex(() => this.getTable());
|
|
24
|
+
|
|
25
|
+
// Cached reranker — k=60 is constant, no need to recreate per search
|
|
26
|
+
private getReranker = createRerankerMutex();
|
|
27
|
+
|
|
28
|
+
constructor(private db: lancedb.Connection) {}
|
|
29
|
+
|
|
30
|
+
private getTable(): Promise<Table> {
|
|
31
|
+
if (!this.tablePromise) {
|
|
32
|
+
this.tablePromise = getOrCreateTable(
|
|
33
|
+
this.db,
|
|
34
|
+
CONVERSATION_TABLE_NAME,
|
|
35
|
+
conversationSchema,
|
|
36
|
+
).catch((err) => {
|
|
37
|
+
this.tablePromise = null;
|
|
38
|
+
throw err;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return this.tablePromise;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private rowToConversationHybridRow(
|
|
45
|
+
row: Record<string, unknown>
|
|
46
|
+
): ConversationHybridRow {
|
|
47
|
+
const metadata = safeParseJsonObject(row.metadata as string);
|
|
48
|
+
return {
|
|
49
|
+
id: row.id as string,
|
|
50
|
+
content: row.content as string,
|
|
51
|
+
metadata,
|
|
52
|
+
createdAt: new Date(row.created_at as number),
|
|
53
|
+
rrfScore: (row._relevance_score as number) ?? 0,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async insertBatch(
|
|
58
|
+
rows: Array<{
|
|
59
|
+
id: string;
|
|
60
|
+
vector: number[];
|
|
61
|
+
content: string;
|
|
62
|
+
metadata: string;
|
|
63
|
+
created_at: number;
|
|
64
|
+
session_id: string;
|
|
65
|
+
role: string;
|
|
66
|
+
message_index_start: number;
|
|
67
|
+
message_index_end: number;
|
|
68
|
+
project: string;
|
|
69
|
+
}>
|
|
70
|
+
): Promise<void> {
|
|
71
|
+
if (rows.length === 0) return;
|
|
72
|
+
const table = await this.getTable();
|
|
73
|
+
await table.add(rows);
|
|
74
|
+
// Reset FTS mutex so index existence is re-verified after new data
|
|
75
|
+
this.ensureFtsIndex = createFtsMutex(() => this.getTable());
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async deleteBySessionId(sessionId: string): Promise<void> {
|
|
79
|
+
const table = await this.getTable();
|
|
80
|
+
await table.delete(`session_id = '${escapeSql(sessionId)}'`);
|
|
81
|
+
this.ensureFtsIndex = createFtsMutex(() => this.getTable());
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async findHybrid(
|
|
85
|
+
embedding: number[],
|
|
86
|
+
query: string,
|
|
87
|
+
limit: number,
|
|
88
|
+
filters?: HistoryFilters
|
|
89
|
+
): Promise<ConversationHybridRow[]> {
|
|
90
|
+
await this.ensureFtsIndex();
|
|
91
|
+
const table = await this.getTable();
|
|
92
|
+
const reranker = await this.getReranker();
|
|
93
|
+
|
|
94
|
+
let queryBuilder = table
|
|
95
|
+
.query()
|
|
96
|
+
.nearestTo(embedding)
|
|
97
|
+
.fullTextSearch(query)
|
|
98
|
+
.rerank(reranker);
|
|
99
|
+
|
|
100
|
+
const conditions: string[] = [];
|
|
101
|
+
if (filters?.sessionId)
|
|
102
|
+
conditions.push(`session_id = '${escapeSql(filters.sessionId)}'`);
|
|
103
|
+
if (filters?.role) conditions.push(`role = '${escapeSql(filters.role)}'`);
|
|
104
|
+
if (filters?.project)
|
|
105
|
+
conditions.push(`project = '${escapeSql(filters.project)}'`);
|
|
106
|
+
if (filters?.after)
|
|
107
|
+
conditions.push(`created_at > ${filters.after.getTime()}`);
|
|
108
|
+
if (filters?.before)
|
|
109
|
+
conditions.push(`created_at < ${filters.before.getTime()}`);
|
|
110
|
+
|
|
111
|
+
if (conditions.length > 0) {
|
|
112
|
+
queryBuilder = queryBuilder.where(conditions.join(" AND "));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const results = await queryBuilder.limit(limit).toArray();
|
|
116
|
+
return results.map((row) =>
|
|
117
|
+
this.rowToConversationHybridRow(row as Record<string, unknown>)
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Schema,
|
|
3
|
+
Field,
|
|
4
|
+
FixedSizeList,
|
|
5
|
+
Float32,
|
|
6
|
+
Utf8,
|
|
7
|
+
Timestamp,
|
|
8
|
+
TimeUnit,
|
|
9
|
+
Int32,
|
|
10
|
+
} from "apache-arrow";
|
|
11
|
+
|
|
12
|
+
export const CONVERSATION_TABLE_NAME = "conversation_history";
|
|
13
|
+
|
|
14
|
+
export const conversationSchema = new Schema([
|
|
15
|
+
new Field("id", new Utf8(), false),
|
|
16
|
+
new Field(
|
|
17
|
+
"vector",
|
|
18
|
+
new FixedSizeList(384, new Field("item", new Float32(), false)),
|
|
19
|
+
false
|
|
20
|
+
),
|
|
21
|
+
new Field("content", new Utf8(), false),
|
|
22
|
+
new Field("metadata", new Utf8(), false), // JSON string
|
|
23
|
+
new Field(
|
|
24
|
+
"created_at",
|
|
25
|
+
new Timestamp(TimeUnit.MILLISECOND),
|
|
26
|
+
false
|
|
27
|
+
),
|
|
28
|
+
new Field("session_id", new Utf8(), false),
|
|
29
|
+
new Field("role", new Utf8(), false),
|
|
30
|
+
new Field("message_index_start", new Int32(), false),
|
|
31
|
+
new Field("message_index_end", new Int32(), false),
|
|
32
|
+
new Field("project", new Utf8(), false),
|
|
33
|
+
]);
|
package/src/db/lancedb-utils.ts
CHANGED
|
@@ -3,13 +3,20 @@ import { Index, rerankers, type Table } from "@lancedb/lancedb";
|
|
|
3
3
|
import type { Schema } from "apache-arrow";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Escape a string value for safe interpolation into LanceDB/DataFusion SQL WHERE clauses.
|
|
7
|
+
*
|
|
8
|
+
* DataFusion uses ANSI SQL string literal rules:
|
|
9
|
+
* - String literals are delimited by single quotes
|
|
10
|
+
* - Single quotes within strings are escaped by doubling: ' -> ''
|
|
11
|
+
* - Backslashes are NOT escape characters (treated literally)
|
|
8
12
|
*/
|
|
9
|
-
export function
|
|
13
|
+
export function escapeSql(value: string): string {
|
|
10
14
|
return value.replace(/'/g, "''");
|
|
11
15
|
}
|
|
12
16
|
|
|
17
|
+
/** Default k parameter for Reciprocal Rank Fusion reranking. */
|
|
18
|
+
export const RRF_K = 60;
|
|
19
|
+
|
|
13
20
|
/**
|
|
14
21
|
* Converts LanceDB's Arrow Vector type to a plain number[].
|
|
15
22
|
* LanceDB returns an Arrow Vector object which is iterable but not an array.
|
|
@@ -20,6 +27,17 @@ export function arrowVectorToArray(value: unknown): number[] {
|
|
|
20
27
|
: (Array.from(value as Iterable<number>) as number[]);
|
|
21
28
|
}
|
|
22
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Safely parse a JSON string into an object, returning an empty object on failure.
|
|
32
|
+
*/
|
|
33
|
+
export function safeParseJsonObject(raw: string): Record<string, unknown> {
|
|
34
|
+
try {
|
|
35
|
+
return JSON.parse(raw);
|
|
36
|
+
} catch {
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
23
41
|
/**
|
|
24
42
|
* Opens an existing table or creates it with the given schema.
|
|
25
43
|
* Does NOT cache — callers should cache the returned Table if desired.
|
|
@@ -29,11 +47,21 @@ export async function getOrCreateTable(
|
|
|
29
47
|
name: string,
|
|
30
48
|
schema: Schema
|
|
31
49
|
): Promise<Table> {
|
|
32
|
-
|
|
33
|
-
|
|
50
|
+
try {
|
|
51
|
+
return await db.openTable(name);
|
|
52
|
+
} catch (err: unknown) {
|
|
53
|
+
// Only proceed to create if the table was not found
|
|
54
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
55
|
+
if (!message.includes("was not found") && !message.includes("does not exist")) {
|
|
56
|
+
throw err;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
return await db.createTable(name, [], { schema });
|
|
61
|
+
} catch {
|
|
62
|
+
// Another caller may have created it concurrently
|
|
34
63
|
return await db.openTable(name);
|
|
35
64
|
}
|
|
36
|
-
return await db.createTable(name, [], { schema });
|
|
37
65
|
}
|
|
38
66
|
|
|
39
67
|
/**
|
|
@@ -81,7 +109,7 @@ export function createFtsMutex(
|
|
|
81
109
|
* Same pattern as createFtsMutex: create once, cache forever, reset on error.
|
|
82
110
|
*/
|
|
83
111
|
export function createRerankerMutex(
|
|
84
|
-
k: number =
|
|
112
|
+
k: number = RRF_K
|
|
85
113
|
): () => Promise<rerankers.RRFReranker> {
|
|
86
114
|
let promise: Promise<rerankers.RRFReranker> | null = null;
|
|
87
115
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as lancedb from "@lancedb/lancedb";
|
|
2
2
|
import { type Table } from "@lancedb/lancedb";
|
|
3
3
|
import { TABLE_NAME, memorySchema } from "./schema.js";
|
|
4
|
-
import { arrowVectorToArray, createFtsMutex, createRerankerMutex,
|
|
4
|
+
import { arrowVectorToArray, createFtsMutex, createRerankerMutex, escapeSql, safeParseJsonObject } from "./lancedb-utils.js";
|
|
5
5
|
import {
|
|
6
6
|
type Memory,
|
|
7
7
|
type HybridRow,
|
|
@@ -83,7 +83,7 @@ export class MemoryRepository {
|
|
|
83
83
|
id: row.id as string,
|
|
84
84
|
content: row.content as string,
|
|
85
85
|
embedding: arrowVectorToArray(row.vector),
|
|
86
|
-
metadata:
|
|
86
|
+
metadata: safeParseJsonObject(row.metadata as string),
|
|
87
87
|
createdAt: new Date(row.created_at as number),
|
|
88
88
|
updatedAt: new Date(row.updated_at as number),
|
|
89
89
|
supersededBy: row.superseded_by as string | null,
|
|
@@ -115,14 +115,14 @@ export class MemoryRepository {
|
|
|
115
115
|
|
|
116
116
|
async upsert(memory: Memory): Promise<void> {
|
|
117
117
|
const table = await this.getTable();
|
|
118
|
-
const existing = await table.query().where(`id = '${
|
|
118
|
+
const existing = await table.query().where(`id = '${escapeSql(memory.id)}'`).limit(1).toArray();
|
|
119
119
|
|
|
120
120
|
if (existing.length === 0) {
|
|
121
121
|
return await this.insert(memory);
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
await table.update({
|
|
125
|
-
where: `id = '${
|
|
125
|
+
where: `id = '${escapeSql(memory.id)}'`,
|
|
126
126
|
values: {
|
|
127
127
|
vector: memory.embedding,
|
|
128
128
|
content: memory.content,
|
|
@@ -139,7 +139,7 @@ export class MemoryRepository {
|
|
|
139
139
|
|
|
140
140
|
async findById(id: string): Promise<Memory | null> {
|
|
141
141
|
const table = await this.getTable();
|
|
142
|
-
const results = await table.query().where(`id = '${
|
|
142
|
+
const results = await table.query().where(`id = '${escapeSql(id)}'`).limit(1).toArray();
|
|
143
143
|
|
|
144
144
|
if (results.length === 0) {
|
|
145
145
|
return null;
|
|
@@ -152,14 +152,14 @@ export class MemoryRepository {
|
|
|
152
152
|
const table = await this.getTable();
|
|
153
153
|
|
|
154
154
|
// Verify existence first to match previous behavior (return false if not found)
|
|
155
|
-
const existing = await table.query().where(`id = '${
|
|
155
|
+
const existing = await table.query().where(`id = '${escapeSql(id)}'`).limit(1).toArray();
|
|
156
156
|
if (existing.length === 0) {
|
|
157
157
|
return false;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
const now = Date.now();
|
|
161
161
|
await table.update({
|
|
162
|
-
where: `id = '${
|
|
162
|
+
where: `id = '${escapeSql(id)}'`,
|
|
163
163
|
values: {
|
|
164
164
|
superseded_by: DELETED_TOMBSTONE,
|
|
165
165
|
updated_at: now,
|
package/src/http/server.ts
CHANGED
|
@@ -85,6 +85,7 @@ export function createHttpApp(memoryService: MemoryService, config: Config): Hon
|
|
|
85
85
|
dbPath: config.dbPath,
|
|
86
86
|
embeddingModel: config.embeddingModel,
|
|
87
87
|
embeddingDimension: config.embeddingDimension,
|
|
88
|
+
historyEnabled: config.conversationHistory.enabled,
|
|
88
89
|
},
|
|
89
90
|
});
|
|
90
91
|
});
|
|
@@ -101,16 +102,17 @@ export function createHttpApp(memoryService: MemoryService, config: Config): Hon
|
|
|
101
102
|
return c.json({ error: "Missing or invalid 'query' field" }, 400);
|
|
102
103
|
}
|
|
103
104
|
|
|
104
|
-
const
|
|
105
|
+
const results = await memoryService.search(query, intent, limit);
|
|
105
106
|
|
|
106
107
|
return c.json({
|
|
107
|
-
|
|
108
|
-
id:
|
|
109
|
-
content:
|
|
110
|
-
metadata:
|
|
111
|
-
|
|
108
|
+
results: results.map((r) => ({
|
|
109
|
+
id: r.id,
|
|
110
|
+
content: r.content,
|
|
111
|
+
metadata: r.metadata,
|
|
112
|
+
source: r.source,
|
|
113
|
+
createdAt: r.createdAt.toISOString(),
|
|
112
114
|
})),
|
|
113
|
-
count:
|
|
115
|
+
count: results.length,
|
|
114
116
|
});
|
|
115
117
|
} catch (error) {
|
|
116
118
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
@@ -193,6 +195,28 @@ export function createHttpApp(memoryService: MemoryService, config: Config): Hon
|
|
|
193
195
|
}
|
|
194
196
|
});
|
|
195
197
|
|
|
198
|
+
// Index conversations (trigger incremental indexing)
|
|
199
|
+
app.post("/index-conversations", async (c) => {
|
|
200
|
+
try {
|
|
201
|
+
const conversationService = memoryService.getConversationService();
|
|
202
|
+
if (!conversationService) {
|
|
203
|
+
return c.json({ error: "Conversation history indexing is not enabled" }, 400);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const body = await c.req.json().catch(() => ({}));
|
|
207
|
+
const since = body.since ? new Date(body.since as string) : undefined;
|
|
208
|
+
const result = await conversationService.indexConversations(
|
|
209
|
+
body.path as string | undefined,
|
|
210
|
+
since
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
return c.json(result);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
216
|
+
return c.json({ error: message }, 500);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
|
|
196
220
|
// Get single memory
|
|
197
221
|
app.get("/memories/:id", async (c) => {
|
|
198
222
|
try {
|
package/src/index.ts
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
import { loadConfig, parseCliArgs } from "./config/index.js";
|
|
4
4
|
import { connectToDatabase } from "./db/connection.js";
|
|
5
5
|
import { MemoryRepository } from "./db/memory.repository.js";
|
|
6
|
+
import { ConversationRepository } from "./db/conversation.repository.js";
|
|
6
7
|
import { EmbeddingsService } from "./services/embeddings.service.js";
|
|
7
8
|
import { MemoryService } from "./services/memory.service.js";
|
|
8
|
-
import {
|
|
9
|
-
import { ConversationHistoryService } from "./services/conversation-history.service.js";
|
|
9
|
+
import { ConversationHistoryService } from "./services/conversation.service.js";
|
|
10
10
|
import { startServer } from "./mcp/server.js";
|
|
11
11
|
import { startHttpServer } from "./http/server.js";
|
|
12
12
|
|
|
@@ -32,18 +32,17 @@ async function main(): Promise<void> {
|
|
|
32
32
|
const embeddings = new EmbeddingsService(config.embeddingModel, config.embeddingDimension);
|
|
33
33
|
const memoryService = new MemoryService(repository, embeddings);
|
|
34
34
|
|
|
35
|
-
//
|
|
35
|
+
// Conditionally initialize conversation history indexing
|
|
36
36
|
if (config.conversationHistory.enabled) {
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
|
|
37
|
+
const conversationRepository = new ConversationRepository(db);
|
|
38
|
+
const conversationService = new ConversationHistoryService(
|
|
39
|
+
conversationRepository,
|
|
40
40
|
embeddings,
|
|
41
|
-
config.conversationHistory
|
|
42
|
-
|
|
43
|
-
memoryService.setConversationHistory(
|
|
44
|
-
historyService,
|
|
45
|
-
config.conversationHistory.historyWeight,
|
|
41
|
+
config.conversationHistory,
|
|
42
|
+
config.dbPath
|
|
46
43
|
);
|
|
44
|
+
memoryService.setConversationService(conversationService);
|
|
45
|
+
console.error("[vector-memory-mcp] Conversation history indexing enabled");
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
// Track cleanup functions
|