squish-memory 1.0.0 → 1.0.1
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/.env.mcp.example +14 -11
- package/README.md +24 -7
- package/bin/squish-add.mjs +32 -0
- package/bin/squish-rm.mjs +21 -0
- package/config/settings.json +51 -0
- package/dist/api/web/web.d.ts.map +1 -1
- package/dist/api/web/web.js +452 -451
- package/dist/api/web/web.js.map +1 -1
- package/dist/commands/mcp-server.js +7 -3
- package/dist/commands/mcp-server.js.map +1 -1
- package/dist/config.d.ts +10 -10
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +78 -23
- package/dist/config.js.map +1 -1
- package/dist/core/embeddings.d.ts +1 -1
- package/dist/core/embeddings.d.ts.map +1 -1
- package/dist/core/embeddings.js +10 -67
- package/dist/core/embeddings.js.map +1 -1
- package/dist/core/local-embeddings.d.ts +3 -11
- package/dist/core/local-embeddings.d.ts.map +1 -1
- package/dist/core/local-embeddings.js +2 -76
- package/dist/core/local-embeddings.js.map +1 -1
- package/dist/core/memory/context-collector.d.ts.map +1 -1
- package/dist/core/memory/context-collector.js +3 -2
- package/dist/core/memory/context-collector.js.map +1 -1
- package/dist/core/memory/feedback-tracker.d.ts.map +1 -1
- package/dist/core/memory/feedback-tracker.js +10 -6
- package/dist/core/memory/feedback-tracker.js.map +1 -1
- package/dist/core/memory/hybrid-search.js +32 -32
- package/dist/core/memory/memories.js +46 -46
- package/dist/core/memory/query-rewriter.js +9 -9
- package/dist/core/memory/stats.js +5 -5
- package/dist/core/namespaces/index.d.ts.map +1 -1
- package/dist/core/namespaces/index.js +20 -11
- package/dist/core/namespaces/index.js.map +1 -1
- package/dist/core/scheduler/cron-scheduler.d.ts.map +1 -1
- package/dist/core/scheduler/cron-scheduler.js +12 -7
- package/dist/core/scheduler/cron-scheduler.js.map +1 -1
- package/dist/core/scheduler/job-runner.js +8 -5
- package/dist/core/scheduler/job-runner.js.map +1 -1
- package/dist/core/search/conversations.js +33 -33
- package/dist/core/session-hooks/self-iteration-job.d.ts.map +1 -1
- package/dist/core/session-hooks/self-iteration-job.js +43 -39
- package/dist/core/session-hooks/self-iteration-job.js.map +1 -1
- package/dist/core/session-hooks/session-hooks.d.ts.map +1 -1
- package/dist/core/session-hooks/session-hooks.js +6 -3
- package/dist/core/session-hooks/session-hooks.js.map +1 -1
- package/dist/core/tracing/collector.d.ts.map +1 -1
- package/dist/core/tracing/collector.js +25 -13
- package/dist/core/tracing/collector.js.map +1 -1
- package/dist/db/adapter.d.ts +6 -1
- package/dist/db/adapter.d.ts.map +1 -1
- package/dist/db/adapter.js +54 -126
- package/dist/db/adapter.js.map +1 -1
- package/dist/db/bootstrap.js +477 -477
- package/dist/db/index.d.ts +5 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +46 -45
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Utility functions for local embeddings
|
|
3
|
+
* Note: Actual embedding generation is in core/embeddings.ts
|
|
4
4
|
*/
|
|
5
|
-
export
|
|
6
|
-
export declare const EMBEDDING_DIMENSIONS = 1536;
|
|
7
|
-
export interface EmbeddingProvider {
|
|
8
|
-
embed(text: string): Promise<Embedding>;
|
|
9
|
-
isAvailable(): Promise<boolean>;
|
|
10
|
-
getDimensions(): number;
|
|
11
|
-
}
|
|
12
|
-
export declare function initializeEmbeddingProvider(): Promise<void>;
|
|
13
|
-
export declare function cosineSimilarity(a: Embedding, b: Embedding): number;
|
|
5
|
+
export declare function cosineSimilarity(a: number[], b: number[]): number;
|
|
14
6
|
//# sourceMappingURL=local-embeddings.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-embeddings.d.ts","sourceRoot":"","sources":["../../core/local-embeddings.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"local-embeddings.d.ts","sourceRoot":"","sources":["../../core/local-embeddings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAiBjE"}
|
|
@@ -1,81 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Utility functions for local embeddings
|
|
3
|
+
* Note: Actual embedding generation is in core/embeddings.ts
|
|
4
4
|
*/
|
|
5
|
-
import { config } from '../config.js';
|
|
6
|
-
import { logger } from './logger.js';
|
|
7
|
-
export const EMBEDDING_DIMENSIONS = 1536;
|
|
8
|
-
class StubEmbeddingProvider {
|
|
9
|
-
async embed(_text) {
|
|
10
|
-
return Array(EMBEDDING_DIMENSIONS).fill(0);
|
|
11
|
-
}
|
|
12
|
-
async isAvailable() {
|
|
13
|
-
return true;
|
|
14
|
-
}
|
|
15
|
-
getDimensions() {
|
|
16
|
-
return EMBEDDING_DIMENSIONS;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
class LocalTfidfEmbeddingProvider {
|
|
20
|
-
idf = new Map();
|
|
21
|
-
async embed(text) {
|
|
22
|
-
const words = this.tokenize(text);
|
|
23
|
-
const embedding = Array(EMBEDDING_DIMENSIONS).fill(0);
|
|
24
|
-
const wordFreq = new Map();
|
|
25
|
-
for (const word of words) {
|
|
26
|
-
wordFreq.set(word, (wordFreq.get(word) || 0) + 1);
|
|
27
|
-
}
|
|
28
|
-
for (const [word, freq] of wordFreq.entries()) {
|
|
29
|
-
const hash = this.hash(word) % EMBEDDING_DIMENSIONS;
|
|
30
|
-
const idf = this.idf.get(word) || 1;
|
|
31
|
-
embedding[hash] += freq * idf;
|
|
32
|
-
}
|
|
33
|
-
const norm = Math.sqrt(embedding.reduce((sum, val) => sum + val * val, 0));
|
|
34
|
-
if (norm > 0) {
|
|
35
|
-
for (let i = 0; i < embedding.length; i++) {
|
|
36
|
-
embedding[i] /= norm;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return embedding;
|
|
40
|
-
}
|
|
41
|
-
async isAvailable() {
|
|
42
|
-
return true;
|
|
43
|
-
}
|
|
44
|
-
getDimensions() {
|
|
45
|
-
return EMBEDDING_DIMENSIONS;
|
|
46
|
-
}
|
|
47
|
-
tokenize(text) {
|
|
48
|
-
return text.toLowerCase().split(/\s+/).filter(w => w.length > 2).slice(0, 100);
|
|
49
|
-
}
|
|
50
|
-
hash(str) {
|
|
51
|
-
let hash = 0;
|
|
52
|
-
for (let i = 0; i < str.length; i++) {
|
|
53
|
-
hash = ((hash << 5) - hash) + str.charCodeAt(i);
|
|
54
|
-
hash = hash & hash;
|
|
55
|
-
}
|
|
56
|
-
return Math.abs(hash);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
let currentProvider = null;
|
|
60
|
-
export async function initializeEmbeddingProvider() {
|
|
61
|
-
if (config.embeddingsProvider === 'openai' && config.openAiApiKey) {
|
|
62
|
-
logger.info('Using OpenAI embeddings (team mode - requires API key)');
|
|
63
|
-
currentProvider = new StubEmbeddingProvider();
|
|
64
|
-
}
|
|
65
|
-
else if (config.embeddingsProvider === 'ollama') {
|
|
66
|
-
logger.info('Using Ollama embeddings (team mode - local LLM)');
|
|
67
|
-
currentProvider = new StubEmbeddingProvider();
|
|
68
|
-
}
|
|
69
|
-
else if (config.embeddingsProvider === 'local') {
|
|
70
|
-
logger.info('Using local TF-IDF embeddings (SQLite mode - offline, no API key)');
|
|
71
|
-
currentProvider = new LocalTfidfEmbeddingProvider();
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
// 'none' mode
|
|
75
|
-
logger.info('Embeddings disabled (stub provider)');
|
|
76
|
-
currentProvider = new StubEmbeddingProvider();
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
5
|
export function cosineSimilarity(a, b) {
|
|
80
6
|
if (a.length !== b.length) {
|
|
81
7
|
throw new Error('Embeddings must have same dimensions');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-embeddings.js","sourceRoot":"","sources":["../../core/local-embeddings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,
|
|
1
|
+
{"version":3,"file":"local-embeddings.js","sourceRoot":"","sources":["../../core/local-embeddings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,gBAAgB,CAAC,CAAW,EAAE,CAAW;IACvD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrB,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxD,OAAO,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,WAAW,CAAC;AAC1D,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-collector.d.ts","sourceRoot":"","sources":["../../../core/memory/context-collector.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAOlF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAU,GAChB,OAAO,CAAC,cAAc,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"context-collector.d.ts","sourceRoot":"","sources":["../../../core/memory/context-collector.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAOlF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAU,GAChB,OAAO,CAAC,cAAc,EAAE,CAAC,CAuC3B;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,MAAM,CAMtE;AAED,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAU,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC,CAMnB"}
|
|
@@ -10,7 +10,8 @@ export async function collectRecentContext(sessionId, count = 5) {
|
|
|
10
10
|
return [];
|
|
11
11
|
}
|
|
12
12
|
try {
|
|
13
|
-
const
|
|
13
|
+
const sqliteDb = db;
|
|
14
|
+
const [conversation] = await sqliteDb
|
|
14
15
|
.select()
|
|
15
16
|
.from(conversations)
|
|
16
17
|
.where(eq(conversations.sessionId, sessionId))
|
|
@@ -20,7 +21,7 @@ export async function collectRecentContext(sessionId, count = 5) {
|
|
|
20
21
|
logger.debug(`[ContextCollector] No conversation found for session ${sessionId}`);
|
|
21
22
|
return [];
|
|
22
23
|
}
|
|
23
|
-
const recentMessages = await
|
|
24
|
+
const recentMessages = await sqliteDb
|
|
24
25
|
.select()
|
|
25
26
|
.from(messages)
|
|
26
27
|
.where(eq(messages.conversationId, conversation.id))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-collector.js","sourceRoot":"","sources":["../../../core/memory/context-collector.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAElF,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAQvC,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,SAAiB,EACjB,QAAgB,CAAC;IAEjB,MAAM,EAAE,GAAG,MAAM,KAAK,EAAE,CAAC;IACzB,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QACzD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,CAAC,YAAY,CAAC,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"context-collector.js","sourceRoot":"","sources":["../../../core/memory/context-collector.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feedback-tracker.d.ts","sourceRoot":"","sources":["../../../core/memory/feedback-tracker.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAiB9E,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EAAE,EACnB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"feedback-tracker.d.ts","sourceRoot":"","sources":["../../../core/memory/feedback-tracker.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAiB9E,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EAAE,EACnB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAED,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAgEf;AAaD,wBAAsB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0B5F;AAED,wBAAsB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACtE,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC,CAwBD;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,GAAE,MAAgB,GAAG,IAAI,CAOxE"}
|
|
@@ -19,8 +19,9 @@ export async function recordInjection(sessionId, memoryIds, memoryContent) {
|
|
|
19
19
|
return;
|
|
20
20
|
try {
|
|
21
21
|
const now = new Date();
|
|
22
|
+
const sqliteDb = db;
|
|
22
23
|
for (const memoryId of memoryIds) {
|
|
23
|
-
await
|
|
24
|
+
await sqliteDb.insert(memoryFeedback).values({
|
|
24
25
|
memoryId,
|
|
25
26
|
sessionId,
|
|
26
27
|
wasInjected: true,
|
|
@@ -55,16 +56,17 @@ export async function analyzeAndRecordFeedback(sessionId, responseText) {
|
|
|
55
56
|
return;
|
|
56
57
|
try {
|
|
57
58
|
const now = new Date();
|
|
59
|
+
const sqliteDb = db;
|
|
58
60
|
for (const memoryId of injection.memoryIds) {
|
|
59
61
|
const wasReferenced = analysis.referencedMemoryIds.includes(memoryId);
|
|
60
62
|
const delta = wasReferenced ? config.feedbackEchoBonus : -config.feedbackFizzlePenalty;
|
|
61
|
-
const existing = await
|
|
63
|
+
const existing = await sqliteDb
|
|
62
64
|
.select()
|
|
63
65
|
.from(memoryFeedback)
|
|
64
66
|
.where(and(eq(memoryFeedback.memoryId, memoryId), eq(memoryFeedback.sessionId, sessionId)))
|
|
65
67
|
.limit(1);
|
|
66
68
|
if (existing.length > 0) {
|
|
67
|
-
await
|
|
69
|
+
await sqliteDb
|
|
68
70
|
.update(memoryFeedback)
|
|
69
71
|
.set({
|
|
70
72
|
wasReferenced,
|
|
@@ -99,7 +101,8 @@ export async function updateRetrievalPriority(memoryId, delta) {
|
|
|
99
101
|
if (!db)
|
|
100
102
|
return;
|
|
101
103
|
try {
|
|
102
|
-
const
|
|
104
|
+
const sqliteDb = db;
|
|
105
|
+
const [memory] = await sqliteDb
|
|
103
106
|
.select({ retrievalPriority: memories.retrievalPriority })
|
|
104
107
|
.from(memories)
|
|
105
108
|
.where(eq(memories.id, memoryId))
|
|
@@ -108,7 +111,7 @@ export async function updateRetrievalPriority(memoryId, delta) {
|
|
|
108
111
|
return;
|
|
109
112
|
const currentPriority = memory.retrievalPriority ?? 50;
|
|
110
113
|
const newPriority = Math.max(0, Math.min(100, currentPriority + delta));
|
|
111
|
-
await
|
|
114
|
+
await sqliteDb
|
|
112
115
|
.update(memories)
|
|
113
116
|
.set({ retrievalPriority: newPriority })
|
|
114
117
|
.where(eq(memories.id, memoryId));
|
|
@@ -124,7 +127,8 @@ export async function getMemoryFeedbackStats(memoryId) {
|
|
|
124
127
|
return { totalInjections: 0, totalReferences: 0, echoRate: 0, averagePriorityDelta: 0 };
|
|
125
128
|
}
|
|
126
129
|
try {
|
|
127
|
-
const
|
|
130
|
+
const sqliteDb = db;
|
|
131
|
+
const records = await sqliteDb
|
|
128
132
|
.select()
|
|
129
133
|
.from(memoryFeedback)
|
|
130
134
|
.where(eq(memoryFeedback.memoryId, memoryId));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feedback-tracker.js","sourceRoot":"","sources":["../../../core/memory/feedback-tracker.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAE9E,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAuB,MAAM,gCAAgC,CAAC;AAC/F,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,kCAAkC,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AAQ1G,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA2B,CAAC;AAE5D,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,SAAiB,EACjB,SAAmB,EACnB,aAAkC;IAElC,IAAI,CAAC,MAAM,CAAC,uBAAuB;QAAE,OAAO;IAE5C,gBAAgB,CAAC,GAAG,CAAC,SAAS,EAAE;QAC9B,SAAS;QACT,aAAa;QACb,UAAU,EAAE,IAAI,IAAI,EAAE;KACvB,CAAC,CAAC;IAEH,MAAM,EAAE,GAAG,MAAM,KAAK,EAAE,CAAC;IACzB,IAAI,CAAC,EAAE;QAAE,OAAO;IAEhB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,MAAM,
|
|
1
|
+
{"version":3,"file":"feedback-tracker.js","sourceRoot":"","sources":["../../../core/memory/feedback-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -73,22 +73,22 @@ async function bm25Search(input, options) {
|
|
|
73
73
|
// For empty query with no filters, use "1=1" to match all
|
|
74
74
|
const whereClause = conditions.length > 0 ? conditions.join(' AND ') : '1=1';
|
|
75
75
|
// Build query based on whether we have a search term or not
|
|
76
|
-
const statement = sqlite.prepare(`
|
|
77
|
-
SELECT
|
|
78
|
-
m.id as id,
|
|
79
|
-
m.project_id as projectId,
|
|
80
|
-
m.type as type,
|
|
81
|
-
m.content as content,
|
|
82
|
-
m.summary as summary,
|
|
83
|
-
m.tags as tags,
|
|
84
|
-
m.metadata as metadata,
|
|
85
|
-
${isEmptyQuery ? '0 as bm25Score' : 'bm25(memories_fts) as bm25Score'},
|
|
86
|
-
m.created_at as createdAt
|
|
87
|
-
FROM memories m
|
|
88
|
-
${isEmptyQuery ? '' : 'INNER JOIN memories_fts ON m.rowid = memories_fts.rowid'}
|
|
89
|
-
WHERE ${whereClause}
|
|
90
|
-
${isEmptyQuery ? 'ORDER BY m.created_at DESC' : 'ORDER BY bm25(memories_fts)'}
|
|
91
|
-
LIMIT ?
|
|
76
|
+
const statement = sqlite.prepare(`
|
|
77
|
+
SELECT
|
|
78
|
+
m.id as id,
|
|
79
|
+
m.project_id as projectId,
|
|
80
|
+
m.type as type,
|
|
81
|
+
m.content as content,
|
|
82
|
+
m.summary as summary,
|
|
83
|
+
m.tags as tags,
|
|
84
|
+
m.metadata as metadata,
|
|
85
|
+
${isEmptyQuery ? '0 as bm25Score' : 'bm25(memories_fts) as bm25Score'},
|
|
86
|
+
m.created_at as createdAt
|
|
87
|
+
FROM memories m
|
|
88
|
+
${isEmptyQuery ? '' : 'INNER JOIN memories_fts ON m.rowid = memories_fts.rowid'}
|
|
89
|
+
WHERE ${whereClause}
|
|
90
|
+
${isEmptyQuery ? 'ORDER BY m.created_at DESC' : 'ORDER BY bm25(memories_fts)'}
|
|
91
|
+
LIMIT ?
|
|
92
92
|
`);
|
|
93
93
|
const rows = statement.all(...params, limit * 3);
|
|
94
94
|
// Return as ranked results (lower BM25 score = better rank)
|
|
@@ -154,22 +154,22 @@ async function vectorSearch(input, options) {
|
|
|
154
154
|
? 'WHERE ' + conditions.join(' AND ')
|
|
155
155
|
: '';
|
|
156
156
|
// Fetch candidates for vector search
|
|
157
|
-
const statement = sqlite.prepare(`
|
|
158
|
-
SELECT
|
|
159
|
-
m.id as id,
|
|
160
|
-
m.project_id as projectId,
|
|
161
|
-
m.type as type,
|
|
162
|
-
m.content as content,
|
|
163
|
-
m.summary as summary,
|
|
164
|
-
m.tags as tags,
|
|
165
|
-
m.metadata as metadata,
|
|
166
|
-
m.embedding as embedding,
|
|
167
|
-
m.embedding_json as embeddingJson,
|
|
168
|
-
m.created_at as createdAt
|
|
169
|
-
FROM memories m
|
|
170
|
-
${whereClause}
|
|
171
|
-
ORDER BY m.created_at DESC
|
|
172
|
-
LIMIT ?
|
|
157
|
+
const statement = sqlite.prepare(`
|
|
158
|
+
SELECT
|
|
159
|
+
m.id as id,
|
|
160
|
+
m.project_id as projectId,
|
|
161
|
+
m.type as type,
|
|
162
|
+
m.content as content,
|
|
163
|
+
m.summary as summary,
|
|
164
|
+
m.tags as tags,
|
|
165
|
+
m.metadata as metadata,
|
|
166
|
+
m.embedding as embedding,
|
|
167
|
+
m.embedding_json as embeddingJson,
|
|
168
|
+
m.created_at as createdAt
|
|
169
|
+
FROM memories m
|
|
170
|
+
${whereClause}
|
|
171
|
+
ORDER BY m.created_at DESC
|
|
172
|
+
LIMIT ?
|
|
173
173
|
`);
|
|
174
174
|
const rows = statement.all(...params, limit * 3);
|
|
175
175
|
// If no embedding available, return results ordered by recency
|
|
@@ -257,22 +257,22 @@ async function searchMemoriesSqlite(input, tags, limit) {
|
|
|
257
257
|
const whereClause = conditions.length > 0 ? 'WHERE ' + conditions.join(' AND ') : '';
|
|
258
258
|
// Fetch memories with embeddings for semantic search
|
|
259
259
|
const fetchLimit = Math.max(limit * 3, 50); // Fetch more for re-ranking
|
|
260
|
-
const statement = sqlite.prepare(`
|
|
261
|
-
SELECT
|
|
262
|
-
m.id as id,
|
|
263
|
-
m.project_id as projectId,
|
|
264
|
-
m.type as type,
|
|
265
|
-
m.content as content,
|
|
266
|
-
m.summary as summary,
|
|
267
|
-
m.tags as tags,
|
|
268
|
-
m.metadata as metadata,
|
|
269
|
-
m.embedding as embedding,
|
|
270
|
-
m.embedding_json as embeddingJson,
|
|
271
|
-
m.created_at as createdAt
|
|
272
|
-
FROM memories m
|
|
273
|
-
${whereClause}
|
|
274
|
-
ORDER BY m.created_at DESC
|
|
275
|
-
LIMIT ?
|
|
260
|
+
const statement = sqlite.prepare(`
|
|
261
|
+
SELECT
|
|
262
|
+
m.id as id,
|
|
263
|
+
m.project_id as projectId,
|
|
264
|
+
m.type as type,
|
|
265
|
+
m.content as content,
|
|
266
|
+
m.summary as summary,
|
|
267
|
+
m.tags as tags,
|
|
268
|
+
m.metadata as metadata,
|
|
269
|
+
m.embedding as embedding,
|
|
270
|
+
m.embedding_json as embeddingJson,
|
|
271
|
+
m.created_at as createdAt
|
|
272
|
+
FROM memories m
|
|
273
|
+
${whereClause}
|
|
274
|
+
ORDER BY m.created_at DESC
|
|
275
|
+
LIMIT ?
|
|
276
276
|
`);
|
|
277
277
|
const rows = statement.all(...params, fetchLimit);
|
|
278
278
|
if (rows.length === 0)
|
|
@@ -326,42 +326,42 @@ async function searchMemoriesPostgres(input, tags, limit) {
|
|
|
326
326
|
const whereClause = whereParts.length ? `WHERE ${whereParts.join(' AND ')}` : '';
|
|
327
327
|
const embedding = await getEmbedding(input.query);
|
|
328
328
|
if (embedding) {
|
|
329
|
-
const rows = await db.$client.query(`SELECT
|
|
330
|
-
id,
|
|
331
|
-
project_id as "projectId",
|
|
332
|
-
type,
|
|
333
|
-
content,
|
|
334
|
-
summary,
|
|
335
|
-
tags,
|
|
336
|
-
metadata,
|
|
337
|
-
created_at as "createdAt",
|
|
338
|
-
valid_from as "validFrom",
|
|
339
|
-
valid_to as "validTo",
|
|
340
|
-
recorded_at as "recordedAt"
|
|
341
|
-
FROM memories
|
|
342
|
-
${whereClause}
|
|
343
|
-
ORDER BY created_at DESC
|
|
329
|
+
const rows = await db.$client.query(`SELECT
|
|
330
|
+
id,
|
|
331
|
+
project_id as "projectId",
|
|
332
|
+
type,
|
|
333
|
+
content,
|
|
334
|
+
summary,
|
|
335
|
+
tags,
|
|
336
|
+
metadata,
|
|
337
|
+
created_at as "createdAt",
|
|
338
|
+
valid_from as "validFrom",
|
|
339
|
+
valid_to as "validTo",
|
|
340
|
+
recorded_at as "recordedAt"
|
|
341
|
+
FROM memories
|
|
342
|
+
${whereClause}
|
|
343
|
+
ORDER BY created_at DESC
|
|
344
344
|
LIMIT $${values.length + 1}`, [...values, limit]);
|
|
345
345
|
return rows.rows.map((row) => ({
|
|
346
346
|
...normalizeMemory(row),
|
|
347
347
|
similarity: row.similarity ?? 0,
|
|
348
348
|
}));
|
|
349
349
|
}
|
|
350
|
-
const rows = await db.$client.query(`SELECT
|
|
351
|
-
id,
|
|
352
|
-
project_id as "projectId",
|
|
353
|
-
type,
|
|
354
|
-
content,
|
|
355
|
-
summary,
|
|
356
|
-
tags,
|
|
357
|
-
metadata,
|
|
358
|
-
created_at as "createdAt",
|
|
359
|
-
valid_from as "validFrom",
|
|
360
|
-
valid_to as "validTo",
|
|
361
|
-
recorded_at as "recordedAt"
|
|
362
|
-
FROM memories
|
|
363
|
-
${whereClause}
|
|
364
|
-
ORDER BY created_at DESC
|
|
350
|
+
const rows = await db.$client.query(`SELECT
|
|
351
|
+
id,
|
|
352
|
+
project_id as "projectId",
|
|
353
|
+
type,
|
|
354
|
+
content,
|
|
355
|
+
summary,
|
|
356
|
+
tags,
|
|
357
|
+
metadata,
|
|
358
|
+
created_at as "createdAt",
|
|
359
|
+
valid_from as "validFrom",
|
|
360
|
+
valid_to as "validTo",
|
|
361
|
+
recorded_at as "recordedAt"
|
|
362
|
+
FROM memories
|
|
363
|
+
${whereClause}
|
|
364
|
+
ORDER BY created_at DESC
|
|
365
365
|
LIMIT $${values.length + 1}`, [...values, limit]);
|
|
366
366
|
return rows.rows.map((row) => ({
|
|
367
367
|
...normalizeMemory(row),
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
import { logger } from '../logger.js';
|
|
3
3
|
import { config } from '../../config.js';
|
|
4
4
|
import { expandQuery } from './query-processor.js';
|
|
5
|
-
const REWRITE_SYSTEM_PROMPT = `You are a search query optimizer. Given a conversation context and a user's latest message, rewrite the message into the single most effective search query to retrieve relevant memories.
|
|
6
|
-
|
|
7
|
-
Rules:
|
|
8
|
-
1. Output ONLY the optimized search query - no explanations or extra text
|
|
9
|
-
2. Remove filler words (please, can you, etc.)
|
|
10
|
-
3. Focus on the core information need
|
|
11
|
-
4. Preserve important entities (names, dates, technical terms)
|
|
12
|
-
5. Add synonyms for key terms if helpful
|
|
13
|
-
6. Consider what memories would be most relevant
|
|
5
|
+
const REWRITE_SYSTEM_PROMPT = `You are a search query optimizer. Given a conversation context and a user's latest message, rewrite the message into the single most effective search query to retrieve relevant memories.
|
|
6
|
+
|
|
7
|
+
Rules:
|
|
8
|
+
1. Output ONLY the optimized search query - no explanations or extra text
|
|
9
|
+
2. Remove filler words (please, can you, etc.)
|
|
10
|
+
3. Focus on the core information need
|
|
11
|
+
4. Preserve important entities (names, dates, technical terms)
|
|
12
|
+
5. Add synonyms for key terms if helpful
|
|
13
|
+
6. Consider what memories would be most relevant
|
|
14
14
|
7. If the message is about recalling something specific, include those details`;
|
|
15
15
|
export async function rewriteQuery(query, context) {
|
|
16
16
|
if (!config.queryRewritingEnabled) {
|
|
@@ -36,11 +36,11 @@ export async function getMemoryStats(projectPath = process.cwd()) {
|
|
|
36
36
|
// Count by type
|
|
37
37
|
if (config.isTeamMode) {
|
|
38
38
|
// PostgreSQL - use raw query for GROUP BY
|
|
39
|
-
const typeCounts = await db.execute(sql `
|
|
40
|
-
SELECT type, COUNT(*) as count
|
|
41
|
-
FROM memories
|
|
42
|
-
${project ? sql `WHERE project_id = ${project.id}` : sql ``}
|
|
43
|
-
GROUP BY type
|
|
39
|
+
const typeCounts = await db.execute(sql `
|
|
40
|
+
SELECT type, COUNT(*) as count
|
|
41
|
+
FROM memories
|
|
42
|
+
${project ? sql `WHERE project_id = ${project.id}` : sql ``}
|
|
43
|
+
GROUP BY type
|
|
44
44
|
`);
|
|
45
45
|
for (const row of typeCounts.rows) {
|
|
46
46
|
stats.byType[row.type] = Number(row.count);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/namespaces/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAS9E,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE7E,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC;IACvB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../core/namespaces/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAS9E,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE7E,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC;IACvB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC,CAqDrF;AA8BD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAwB5E;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgCxB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAuClF;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAmFlF;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,GAAE;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAsC5B;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS/D;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAYjB"}
|
|
@@ -15,7 +15,8 @@ export async function createNamespace(input) {
|
|
|
15
15
|
const schema = await getSchema();
|
|
16
16
|
const id = randomUUID();
|
|
17
17
|
// Check if namespace with same name exists under parent
|
|
18
|
-
const
|
|
18
|
+
const sqliteDb = db;
|
|
19
|
+
const existing = await sqliteDb.select()
|
|
19
20
|
.from(schema.namespaces)
|
|
20
21
|
.where(and(eq(schema.namespaces.projectId, input.projectId), eq(schema.namespaces.name, input.name), input.parentId
|
|
21
22
|
? eq(schema.namespaces.parentId, input.parentId)
|
|
@@ -26,7 +27,7 @@ export async function createNamespace(input) {
|
|
|
26
27
|
}
|
|
27
28
|
// Build namespace path
|
|
28
29
|
const path = await buildNamespacePath(input.projectId, input.name, input.parentId ?? null);
|
|
29
|
-
await
|
|
30
|
+
await sqliteDb.insert(schema.namespaces).values({
|
|
30
31
|
id,
|
|
31
32
|
projectId: input.projectId,
|
|
32
33
|
name: input.name,
|
|
@@ -58,7 +59,8 @@ async function buildNamespacePath(projectId, name, parentId) {
|
|
|
58
59
|
}
|
|
59
60
|
const db = await getDb();
|
|
60
61
|
const schema = await getSchema();
|
|
61
|
-
const
|
|
62
|
+
const sqliteDb = db;
|
|
63
|
+
const [parent] = await sqliteDb.select()
|
|
62
64
|
.from(schema.namespaces)
|
|
63
65
|
.where(eq(schema.namespaces.id, parentId))
|
|
64
66
|
.limit(1);
|
|
@@ -75,7 +77,8 @@ export async function getNamespaceById(id) {
|
|
|
75
77
|
if (!db)
|
|
76
78
|
return null;
|
|
77
79
|
const schema = await getSchema();
|
|
78
|
-
const
|
|
80
|
+
const sqliteDb = db;
|
|
81
|
+
const [row] = await sqliteDb.select()
|
|
79
82
|
.from(schema.namespaces)
|
|
80
83
|
.where(eq(schema.namespaces.id, id))
|
|
81
84
|
.limit(1);
|
|
@@ -104,11 +107,12 @@ export async function resolveNamespacePath(projectId, path) {
|
|
|
104
107
|
if (!db)
|
|
105
108
|
return null;
|
|
106
109
|
const schema = await getSchema();
|
|
110
|
+
const sqliteDb = db;
|
|
107
111
|
let parentId = null;
|
|
108
112
|
let targetNamespace = null;
|
|
109
113
|
// Traverse path segments
|
|
110
114
|
for (const segment of path) {
|
|
111
|
-
const [result] = await
|
|
115
|
+
const [result] = await sqliteDb.select()
|
|
112
116
|
.from(schema.namespaces)
|
|
113
117
|
.where(and(eq(schema.namespaces.projectId, projectId), eq(schema.namespaces.name, segment), parentId
|
|
114
118
|
? eq(schema.namespaces.parentId, parentId)
|
|
@@ -129,8 +133,9 @@ export async function getNamespaceTree(projectId) {
|
|
|
129
133
|
if (!db)
|
|
130
134
|
return [];
|
|
131
135
|
const schema = await getSchema();
|
|
136
|
+
const sqliteDb = db;
|
|
132
137
|
// Get all namespaces for project
|
|
133
|
-
const all = await
|
|
138
|
+
const all = await sqliteDb.select()
|
|
134
139
|
.from(schema.namespaces)
|
|
135
140
|
.where(eq(schema.namespaces.projectId, projectId))
|
|
136
141
|
.orderBy(schema.namespaces.name);
|
|
@@ -167,6 +172,7 @@ export async function getDefaultNamespaces(projectId) {
|
|
|
167
172
|
if (!db)
|
|
168
173
|
return [];
|
|
169
174
|
const schema = await getSchema();
|
|
175
|
+
const sqliteDb = db;
|
|
170
176
|
const created = [];
|
|
171
177
|
const defaults = [
|
|
172
178
|
{ name: 'user', type: 'user', description: 'User-specific memories and preferences' },
|
|
@@ -175,7 +181,7 @@ export async function getDefaultNamespaces(projectId) {
|
|
|
175
181
|
];
|
|
176
182
|
const defaultNames = ['user', 'agent', 'project'];
|
|
177
183
|
// Check all default namespaces at once with IN clause
|
|
178
|
-
const existing = await
|
|
184
|
+
const existing = await sqliteDb.select()
|
|
179
185
|
.from(schema.namespaces)
|
|
180
186
|
.where(and(eq(schema.namespaces.projectId, projectId), eq(schema.namespaces.name, defaultNames[0]), eq(schema.namespaces.type, 'user'), isNull(schema.namespaces.parentId)));
|
|
181
187
|
if (existing.length > 0) {
|
|
@@ -199,7 +205,7 @@ export async function getDefaultNamespaces(projectId) {
|
|
|
199
205
|
}
|
|
200
206
|
// Check remaining defaults sequentially (agent and project)
|
|
201
207
|
for (const defName of defaultNames.slice(1)) {
|
|
202
|
-
const existing = await
|
|
208
|
+
const existing = await sqliteDb.select()
|
|
203
209
|
.from(schema.namespaces)
|
|
204
210
|
.where(and(eq(schema.namespaces.projectId, projectId), eq(schema.namespaces.name, defName), eq(schema.namespaces.type, defName), isNull(schema.namespaces.parentId)))
|
|
205
211
|
.limit(1);
|
|
@@ -237,6 +243,7 @@ export async function listNamespaces(options = {}) {
|
|
|
237
243
|
if (!db)
|
|
238
244
|
return [];
|
|
239
245
|
const schema = await getSchema();
|
|
246
|
+
const sqliteDb = db;
|
|
240
247
|
const conditions = [];
|
|
241
248
|
if (options.projectId) {
|
|
242
249
|
conditions.push(eq(schema.namespaces.projectId, options.projectId));
|
|
@@ -252,7 +259,7 @@ export async function listNamespaces(options = {}) {
|
|
|
252
259
|
conditions.push(eq(schema.namespaces.parentId, options.parentId));
|
|
253
260
|
}
|
|
254
261
|
}
|
|
255
|
-
const rows = await
|
|
262
|
+
const rows = await sqliteDb.select()
|
|
256
263
|
.from(schema.namespaces)
|
|
257
264
|
.where(conditions.length > 0 ? and(...conditions) : undefined)
|
|
258
265
|
.orderBy(schema.namespaces.name);
|
|
@@ -276,7 +283,8 @@ export async function deleteNamespace(id) {
|
|
|
276
283
|
if (!db)
|
|
277
284
|
return;
|
|
278
285
|
const schema = await getSchema();
|
|
279
|
-
|
|
286
|
+
const sqliteDb = db;
|
|
287
|
+
await sqliteDb.delete(schema.namespaces).where(eq(schema.namespaces.id, id));
|
|
280
288
|
logger.info(`[Namespaces] Deleted namespace: ${id}`);
|
|
281
289
|
}
|
|
282
290
|
/**
|
|
@@ -287,7 +295,8 @@ export async function updateNamespace(id, updates) {
|
|
|
287
295
|
if (!db)
|
|
288
296
|
return;
|
|
289
297
|
const schema = await getSchema();
|
|
290
|
-
|
|
298
|
+
const sqliteDb = db;
|
|
299
|
+
await sqliteDb.update(schema.namespaces).set({
|
|
291
300
|
...updates,
|
|
292
301
|
updatedAt: new Date(),
|
|
293
302
|
}).where(eq(schema.namespaces.id, id));
|