sensorium-mcp 2.16.28 → 2.16.30
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/config.d.ts +1 -11
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -49
- package/dist/config.js.map +1 -1
- package/dist/dashboard/presets.d.ts +18 -0
- package/dist/dashboard/presets.d.ts.map +1 -0
- package/dist/dashboard/presets.js +78 -0
- package/dist/dashboard/presets.js.map +1 -0
- package/dist/dashboard/routes.d.ts +33 -0
- package/dist/dashboard/routes.d.ts.map +1 -0
- package/dist/dashboard/routes.js +283 -0
- package/dist/dashboard/routes.js.map +1 -0
- package/dist/dashboard.d.ts +6 -29
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/dashboard.js +6 -1158
- package/dist/dashboard.js.map +1 -1
- package/dist/data/file-storage.d.ts +19 -0
- package/dist/data/file-storage.d.ts.map +1 -0
- package/dist/data/file-storage.js +58 -0
- package/dist/data/file-storage.js.map +1 -0
- package/dist/data/memory/bootstrap.d.ts +40 -0
- package/dist/data/memory/bootstrap.d.ts.map +1 -0
- package/dist/data/memory/bootstrap.js +240 -0
- package/dist/data/memory/bootstrap.js.map +1 -0
- package/dist/data/memory/consolidation.d.ts +12 -0
- package/dist/data/memory/consolidation.d.ts.map +1 -0
- package/dist/data/memory/consolidation.js +248 -0
- package/dist/data/memory/consolidation.js.map +1 -0
- package/dist/data/memory/episodes.d.ts +34 -0
- package/dist/data/memory/episodes.d.ts.map +1 -0
- package/dist/data/memory/episodes.js +89 -0
- package/dist/data/memory/episodes.js.map +1 -0
- package/dist/data/memory/index.d.ts +14 -0
- package/dist/data/memory/index.d.ts.map +1 -0
- package/dist/data/memory/index.js +14 -0
- package/dist/data/memory/index.js.map +1 -0
- package/dist/data/memory/procedures.d.ts +42 -0
- package/dist/data/memory/procedures.d.ts.map +1 -0
- package/dist/data/memory/procedures.js +122 -0
- package/dist/data/memory/procedures.js.map +1 -0
- package/dist/data/memory/schema.d.ts +11 -0
- package/dist/data/memory/schema.d.ts.map +1 -0
- package/dist/data/memory/schema.js +327 -0
- package/dist/data/memory/schema.js.map +1 -0
- package/dist/data/memory/semantic.d.ts +94 -0
- package/dist/data/memory/semantic.d.ts.map +1 -0
- package/dist/data/memory/semantic.js +385 -0
- package/dist/data/memory/semantic.js.map +1 -0
- package/dist/data/memory/voice-sig.d.ts +33 -0
- package/dist/data/memory/voice-sig.d.ts.map +1 -0
- package/dist/data/memory/voice-sig.js +48 -0
- package/dist/data/memory/voice-sig.js.map +1 -0
- package/dist/data/templates.d.ts +19 -0
- package/dist/data/templates.d.ts.map +1 -0
- package/dist/data/templates.js +46 -0
- package/dist/data/templates.js.map +1 -0
- package/dist/dispatcher.d.ts +5 -97
- package/dist/dispatcher.d.ts.map +1 -1
- package/dist/dispatcher.js +5 -525
- package/dist/dispatcher.js.map +1 -1
- package/dist/drive.d.ts.map +1 -1
- package/dist/drive.js +3 -1
- package/dist/drive.js.map +1 -1
- package/dist/index.d.ts +4 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -289
- package/dist/index.js.map +1 -1
- package/dist/integrations/openai/chat.d.ts +29 -0
- package/dist/integrations/openai/chat.d.ts.map +1 -0
- package/dist/integrations/openai/chat.js +84 -0
- package/dist/integrations/openai/chat.js.map +1 -0
- package/dist/integrations/openai/index.d.ts +6 -0
- package/dist/integrations/openai/index.d.ts.map +1 -0
- package/dist/integrations/openai/index.js +6 -0
- package/dist/integrations/openai/index.js.map +1 -0
- package/dist/integrations/openai/speech.d.ts +21 -0
- package/dist/integrations/openai/speech.d.ts.map +1 -0
- package/dist/integrations/openai/speech.js +75 -0
- package/dist/integrations/openai/speech.js.map +1 -0
- package/dist/integrations/openai/video.d.ts +15 -0
- package/dist/integrations/openai/video.d.ts.map +1 -0
- package/dist/integrations/openai/video.js +131 -0
- package/dist/integrations/openai/video.js.map +1 -0
- package/dist/integrations/openai/vision.d.ts +23 -0
- package/dist/integrations/openai/vision.d.ts.map +1 -0
- package/dist/integrations/openai/vision.js +116 -0
- package/dist/integrations/openai/vision.js.map +1 -0
- package/dist/integrations/openai/voice-emotion.d.ts +41 -0
- package/dist/integrations/openai/voice-emotion.d.ts.map +1 -0
- package/dist/integrations/openai/voice-emotion.js +50 -0
- package/dist/integrations/openai/voice-emotion.js.map +1 -0
- package/dist/integrations/telegram/types.d.ts +112 -0
- package/dist/integrations/telegram/types.d.ts.map +1 -0
- package/dist/integrations/telegram/types.js +6 -0
- package/dist/integrations/telegram/types.js.map +1 -0
- package/dist/memory.d.ts +6 -205
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +6 -1357
- package/dist/memory.js.map +1 -1
- package/dist/openai.d.ts +11 -102
- package/dist/openai.d.ts.map +1 -1
- package/dist/openai.js +14 -421
- package/dist/openai.js.map +1 -1
- package/dist/response-builders.d.ts +1 -11
- package/dist/response-builders.d.ts.map +1 -1
- package/dist/response-builders.js +2 -38
- package/dist/response-builders.js.map +1 -1
- package/dist/server/factory.d.ts +17 -0
- package/dist/server/factory.d.ts.map +1 -0
- package/dist/server/factory.js +279 -0
- package/dist/server/factory.js.map +1 -0
- package/dist/services/dispatcher/broker.d.ts +83 -0
- package/dist/services/dispatcher/broker.d.ts.map +1 -0
- package/dist/services/dispatcher/broker.js +175 -0
- package/dist/services/dispatcher/broker.js.map +1 -0
- package/dist/services/dispatcher/index.d.ts +7 -0
- package/dist/services/dispatcher/index.d.ts.map +1 -0
- package/dist/services/dispatcher/index.js +7 -0
- package/dist/services/dispatcher/index.js.map +1 -0
- package/dist/services/dispatcher/lock.d.ts +25 -0
- package/dist/services/dispatcher/lock.d.ts.map +1 -0
- package/dist/services/dispatcher/lock.js +111 -0
- package/dist/services/dispatcher/lock.js.map +1 -0
- package/dist/services/dispatcher/poller.d.ts +19 -0
- package/dist/services/dispatcher/poller.d.ts.map +1 -0
- package/dist/services/dispatcher/poller.js +269 -0
- package/dist/services/dispatcher/poller.js.map +1 -0
- package/dist/telegram.d.ts +2 -88
- package/dist/telegram.d.ts.map +1 -1
- package/dist/telegram.js +2 -0
- package/dist/telegram.js.map +1 -1
- package/dist/tool-definitions.d.ts +1 -14
- package/dist/tool-definitions.d.ts.map +1 -1
- package/dist/tool-definitions.js +1 -403
- package/dist/tool-definitions.js.map +1 -1
- package/dist/tools/definitions.d.ts +15 -0
- package/dist/tools/definitions.d.ts.map +1 -0
- package/dist/tools/definitions.js +404 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/start-session-tool.d.ts.map +1 -1
- package/dist/tools/start-session-tool.js +2 -0
- package/dist/tools/start-session-tool.js.map +1 -1
- package/dist/tools/wait/drive-handler.d.ts +61 -0
- package/dist/tools/wait/drive-handler.d.ts.map +1 -0
- package/dist/tools/wait/drive-handler.js +138 -0
- package/dist/tools/wait/drive-handler.js.map +1 -0
- package/dist/tools/wait/index.d.ts +8 -0
- package/dist/tools/wait/index.d.ts.map +1 -0
- package/dist/tools/wait/index.js +8 -0
- package/dist/tools/wait/index.js.map +1 -0
- package/dist/tools/wait/media-processor.d.ts +52 -0
- package/dist/tools/wait/media-processor.d.ts.map +1 -0
- package/dist/tools/wait/media-processor.js +261 -0
- package/dist/tools/wait/media-processor.js.map +1 -0
- package/dist/tools/wait/message-delivery.d.ts +63 -0
- package/dist/tools/wait/message-delivery.d.ts.map +1 -0
- package/dist/tools/wait/message-delivery.js +281 -0
- package/dist/tools/wait/message-delivery.js.map +1 -0
- package/dist/tools/wait/poll-loop.d.ts +72 -0
- package/dist/tools/wait/poll-loop.d.ts.map +1 -0
- package/dist/tools/wait/poll-loop.js +280 -0
- package/dist/tools/wait/poll-loop.js.map +1 -0
- package/dist/tools/wait/reaction-handler.d.ts +49 -0
- package/dist/tools/wait/reaction-handler.d.ts.map +1 -0
- package/dist/tools/wait/reaction-handler.js +126 -0
- package/dist/tools/wait/reaction-handler.js.map +1 -0
- package/dist/tools/wait/task-handler.d.ts +40 -0
- package/dist/tools/wait/task-handler.d.ts.map +1 -0
- package/dist/tools/wait/task-handler.js +41 -0
- package/dist/tools/wait/task-handler.js.map +1 -0
- package/dist/tools/wait-tool.d.ts +3 -69
- package/dist/tools/wait-tool.d.ts.map +1 -1
- package/dist/tools/wait-tool.js +3 -876
- package/dist/tools/wait-tool.js.map +1 -1
- package/package.json +1 -1
- package/templates/daily-review.default.md +26 -0
- package/templates/drive-dispatcher.default.md +2 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic note CRUD operations for the memory system.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from memory.ts — semantic memory layer.
|
|
5
|
+
*/
|
|
6
|
+
import { randomUUID } from "crypto";
|
|
7
|
+
import { cosineSimilarity } from "../../openai.js";
|
|
8
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
9
|
+
function generateId(prefix) {
|
|
10
|
+
return `${prefix}_${randomUUID().replace(/-/g, "").slice(0, 12)}`;
|
|
11
|
+
}
|
|
12
|
+
function nowISO() {
|
|
13
|
+
return new Date().toISOString();
|
|
14
|
+
}
|
|
15
|
+
function jsonOrNull(val) {
|
|
16
|
+
if (val === undefined || val === null)
|
|
17
|
+
return null;
|
|
18
|
+
return JSON.stringify(val);
|
|
19
|
+
}
|
|
20
|
+
function parseJsonArray(val) {
|
|
21
|
+
if (!val)
|
|
22
|
+
return [];
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(val);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function parseJsonObject(val) {
|
|
31
|
+
if (!val)
|
|
32
|
+
return {};
|
|
33
|
+
try {
|
|
34
|
+
return JSON.parse(val);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// ─── Row → Interface mappers ─────────────────────────────────────────────────
|
|
41
|
+
function rowToSemanticNote(row) {
|
|
42
|
+
return {
|
|
43
|
+
noteId: row.note_id,
|
|
44
|
+
type: row.type,
|
|
45
|
+
content: row.content,
|
|
46
|
+
keywords: parseJsonArray(row.keywords),
|
|
47
|
+
confidence: row.confidence,
|
|
48
|
+
priority: row.priority ?? 0,
|
|
49
|
+
threadId: row.thread_id ?? null,
|
|
50
|
+
sourceEpisodes: parseJsonArray(row.source_episodes),
|
|
51
|
+
linkedNotes: parseJsonArray(row.linked_notes),
|
|
52
|
+
linkReasons: parseJsonObject(row.link_reasons),
|
|
53
|
+
validFrom: row.valid_from,
|
|
54
|
+
validTo: row.valid_to ?? null,
|
|
55
|
+
supersededBy: row.superseded_by ?? null,
|
|
56
|
+
accessCount: row.access_count,
|
|
57
|
+
lastAccessed: row.last_accessed ?? null,
|
|
58
|
+
createdAt: row.created_at,
|
|
59
|
+
updatedAt: row.updated_at,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// ─── Topic Index ─────────────────────────────────────────────────────────────
|
|
63
|
+
export function updateTopicIndexForKeywords(db, keywords, layer) {
|
|
64
|
+
const now = nowISO();
|
|
65
|
+
const col = layer === "semantic" ? "semantic_count" : "procedural_count";
|
|
66
|
+
const upsertStmt = db.prepare(`INSERT INTO meta_topic_index (topic, ${col}, last_updated)
|
|
67
|
+
VALUES (?, 1, ?)
|
|
68
|
+
ON CONFLICT(topic) DO UPDATE SET
|
|
69
|
+
${col} = ${col} + 1,
|
|
70
|
+
last_updated = ?,
|
|
71
|
+
total_accesses = total_accesses + 1`);
|
|
72
|
+
const txn = db.transaction(() => {
|
|
73
|
+
for (const kw of keywords) {
|
|
74
|
+
const normalised = kw.toLowerCase().trim();
|
|
75
|
+
if (normalised.length > 1) {
|
|
76
|
+
upsertStmt.run(normalised, now, now);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
txn();
|
|
81
|
+
}
|
|
82
|
+
export function decrementTopicIndexForKeywords(db, keywords, layer) {
|
|
83
|
+
const col = layer === "semantic" ? "semantic_count" : "procedural_count";
|
|
84
|
+
const decrementStmt = db.prepare(`UPDATE meta_topic_index SET ${col} = MAX(${col} - 1, 0) WHERE topic = ?`);
|
|
85
|
+
const deleteStmt = db.prepare(`DELETE FROM meta_topic_index WHERE topic = ? AND semantic_count <= 0 AND procedural_count <= 0`);
|
|
86
|
+
const txn = db.transaction(() => {
|
|
87
|
+
for (const kw of keywords) {
|
|
88
|
+
const normalised = kw.toLowerCase().trim();
|
|
89
|
+
if (normalised.length > 1) {
|
|
90
|
+
decrementStmt.run(normalised);
|
|
91
|
+
deleteStmt.run(normalised);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
txn();
|
|
96
|
+
}
|
|
97
|
+
// ─── Semantic Memory CRUD ────────────────────────────────────────────────────
|
|
98
|
+
export function saveSemanticNote(db, note) {
|
|
99
|
+
const id = generateId("sn");
|
|
100
|
+
const now = nowISO();
|
|
101
|
+
db.prepare(`INSERT INTO semantic_notes
|
|
102
|
+
(note_id, type, content, keywords, confidence, priority, thread_id, source_episodes, linked_notes, link_reasons, valid_from, access_count, created_at, updated_at)
|
|
103
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?, ?)`).run(id, note.type, note.content, JSON.stringify(note.keywords), Math.max(0, Math.min(1, note.confidence ?? 0.5)), Math.max(0, Math.min(2, note.priority ?? 0)), note.threadId ?? null, jsonOrNull(note.sourceEpisodes), null, null, now, now, now);
|
|
104
|
+
// Update topic index for each keyword
|
|
105
|
+
updateTopicIndexForKeywords(db, note.keywords, "semantic");
|
|
106
|
+
return id;
|
|
107
|
+
}
|
|
108
|
+
export function searchSemanticNotes(db, query, options) {
|
|
109
|
+
const maxResults = options?.maxResults ?? 10;
|
|
110
|
+
const terms = query
|
|
111
|
+
.toLowerCase()
|
|
112
|
+
.split(/\s+/)
|
|
113
|
+
.filter((t) => t.length > 1);
|
|
114
|
+
if (terms.length === 0)
|
|
115
|
+
return [];
|
|
116
|
+
// Build LIKE conditions: each term must match content OR keywords
|
|
117
|
+
// Escape SQL LIKE wildcards in search terms
|
|
118
|
+
const conditions = [];
|
|
119
|
+
const params = [];
|
|
120
|
+
for (const term of terms) {
|
|
121
|
+
const escaped = term.replace(/%/g, "\\%").replace(/_/g, "\\_");
|
|
122
|
+
conditions.push(`(LOWER(content) LIKE ? ESCAPE '\\' OR LOWER(keywords) LIKE ? ESCAPE '\\')`);
|
|
123
|
+
params.push(`%${escaped}%`, `%${escaped}%`);
|
|
124
|
+
}
|
|
125
|
+
let sql = `SELECT * FROM semantic_notes WHERE valid_to IS NULL AND superseded_by IS NULL AND (${conditions.join(" AND ")})`;
|
|
126
|
+
if (options?.types && options.types.length > 0) {
|
|
127
|
+
const placeholders = options.types.map(() => "?").join(",");
|
|
128
|
+
sql += ` AND type IN (${placeholders})`;
|
|
129
|
+
params.push(...options.types);
|
|
130
|
+
}
|
|
131
|
+
sql += ` ORDER BY confidence DESC, access_count DESC LIMIT ?`;
|
|
132
|
+
params.push(maxResults);
|
|
133
|
+
const rows = db.prepare(sql).all(...params);
|
|
134
|
+
// Update access counts
|
|
135
|
+
if (!options?.skipAccessTracking) {
|
|
136
|
+
const now = nowISO();
|
|
137
|
+
const updateStmt = db.prepare(`UPDATE semantic_notes SET access_count = access_count + 1, last_accessed = ? WHERE note_id = ?`);
|
|
138
|
+
const txn = db.transaction(() => {
|
|
139
|
+
for (const row of rows) {
|
|
140
|
+
updateStmt.run(now, row.note_id);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
txn();
|
|
144
|
+
}
|
|
145
|
+
return rows.map(rowToSemanticNote);
|
|
146
|
+
}
|
|
147
|
+
export function searchSemanticNotesRanked(db, query, options) {
|
|
148
|
+
const maxResults = options?.maxResults ?? 10;
|
|
149
|
+
const minMatchRatio = options?.minMatchRatio ?? 0.4; // require at least 40% of terms to match
|
|
150
|
+
const terms = query.toLowerCase().split(/\\s+/).filter(t => t.length > 1);
|
|
151
|
+
if (terms.length === 0)
|
|
152
|
+
return [];
|
|
153
|
+
// Use OR to get broad recall
|
|
154
|
+
const conditions = [];
|
|
155
|
+
const params = [];
|
|
156
|
+
for (const term of terms) {
|
|
157
|
+
const escaped = term.replace(/%/g, "\\\\%").replace(/_/g, "\\\\_");
|
|
158
|
+
conditions.push(`(LOWER(content) LIKE ? ESCAPE '\\\\' OR LOWER(keywords) LIKE ? ESCAPE '\\\\')`);
|
|
159
|
+
params.push(`%${escaped}%`, `%${escaped}%`);
|
|
160
|
+
}
|
|
161
|
+
let sql = `SELECT * FROM semantic_notes WHERE valid_to IS NULL AND superseded_by IS NULL AND (${conditions.join(" OR ")})`;
|
|
162
|
+
// Thread filtering: show notes from this thread + global notes
|
|
163
|
+
if (options?.threadId !== undefined) {
|
|
164
|
+
sql += ` AND (thread_id IS NULL OR thread_id = ?)`;
|
|
165
|
+
params.push(options.threadId);
|
|
166
|
+
}
|
|
167
|
+
if (options?.types && options.types.length > 0) {
|
|
168
|
+
const placeholders = options.types.map(() => "?").join(",");
|
|
169
|
+
sql += ` AND type IN (${placeholders})`;
|
|
170
|
+
params.push(...options.types);
|
|
171
|
+
}
|
|
172
|
+
sql += ` ORDER BY confidence DESC, access_count DESC LIMIT ?`;
|
|
173
|
+
params.push(maxResults * 3); // fetch more to allow scoring/filtering
|
|
174
|
+
const rows = db.prepare(sql).all(...params);
|
|
175
|
+
const allNotes = rows.map(rowToSemanticNote);
|
|
176
|
+
// Score by how many terms match
|
|
177
|
+
const minMatches = Math.max(2, Math.ceil(terms.length * minMatchRatio));
|
|
178
|
+
const scored = allNotes.map(n => {
|
|
179
|
+
const text = (n.content + " " + n.keywords.join(" ")).toLowerCase();
|
|
180
|
+
let matchCount = 0;
|
|
181
|
+
for (const term of terms) {
|
|
182
|
+
if (text.includes(term))
|
|
183
|
+
matchCount++;
|
|
184
|
+
}
|
|
185
|
+
return { ...n, _matchCount: matchCount };
|
|
186
|
+
})
|
|
187
|
+
.filter(n => n._matchCount >= minMatches)
|
|
188
|
+
.sort((a, b) => {
|
|
189
|
+
if (b._matchCount !== a._matchCount)
|
|
190
|
+
return b._matchCount - a._matchCount;
|
|
191
|
+
return b.confidence - a.confidence;
|
|
192
|
+
})
|
|
193
|
+
.slice(0, maxResults);
|
|
194
|
+
const notes = scored;
|
|
195
|
+
// Update access counts
|
|
196
|
+
if (!options?.skipAccessTracking) {
|
|
197
|
+
const now = nowISO();
|
|
198
|
+
const updateStmt = db.prepare(`UPDATE semantic_notes SET access_count = access_count + 1, last_accessed = ? WHERE note_id = ?`);
|
|
199
|
+
db.transaction(() => {
|
|
200
|
+
for (const note of notes)
|
|
201
|
+
updateStmt.run(now, note.noteId);
|
|
202
|
+
})();
|
|
203
|
+
}
|
|
204
|
+
return notes;
|
|
205
|
+
}
|
|
206
|
+
export function getTopSemanticNotes(db, options) {
|
|
207
|
+
const limit = options?.limit ?? 10;
|
|
208
|
+
const sortBy = options?.sortBy ?? "confidence";
|
|
209
|
+
const validSortColumns = {
|
|
210
|
+
confidence: "confidence DESC",
|
|
211
|
+
access_count: "access_count DESC",
|
|
212
|
+
created_at: "created_at DESC",
|
|
213
|
+
};
|
|
214
|
+
const orderClause = validSortColumns[sortBy] ?? "confidence DESC";
|
|
215
|
+
let sql = `SELECT * FROM semantic_notes WHERE valid_to IS NULL AND superseded_by IS NULL`;
|
|
216
|
+
const params = [];
|
|
217
|
+
if (options?.type) {
|
|
218
|
+
sql += ` AND type = ?`;
|
|
219
|
+
params.push(options.type);
|
|
220
|
+
}
|
|
221
|
+
sql += ` ORDER BY ${orderClause} LIMIT ?`;
|
|
222
|
+
params.push(limit);
|
|
223
|
+
const rows = db.prepare(sql).all(...params);
|
|
224
|
+
return rows.map(rowToSemanticNote);
|
|
225
|
+
}
|
|
226
|
+
export function updateSemanticNote(db, noteId, updates) {
|
|
227
|
+
const now = nowISO();
|
|
228
|
+
const setClauses = ["updated_at = ?"];
|
|
229
|
+
const params = [now];
|
|
230
|
+
if (updates.content !== undefined) {
|
|
231
|
+
setClauses.push("content = ?");
|
|
232
|
+
params.push(updates.content);
|
|
233
|
+
}
|
|
234
|
+
if (updates.confidence !== undefined) {
|
|
235
|
+
setClauses.push("confidence = ?");
|
|
236
|
+
params.push(updates.confidence);
|
|
237
|
+
}
|
|
238
|
+
if (updates.priority !== undefined) {
|
|
239
|
+
setClauses.push("priority = ?");
|
|
240
|
+
params.push(Math.max(0, Math.min(2, updates.priority)));
|
|
241
|
+
}
|
|
242
|
+
if (updates.keywords !== undefined) {
|
|
243
|
+
setClauses.push("keywords = ?");
|
|
244
|
+
params.push(JSON.stringify(updates.keywords));
|
|
245
|
+
}
|
|
246
|
+
if (updates.linkedNotes !== undefined) {
|
|
247
|
+
setClauses.push("linked_notes = ?");
|
|
248
|
+
params.push(JSON.stringify(updates.linkedNotes));
|
|
249
|
+
}
|
|
250
|
+
if (updates.linkReasons !== undefined) {
|
|
251
|
+
setClauses.push("link_reasons = ?");
|
|
252
|
+
params.push(JSON.stringify(updates.linkReasons));
|
|
253
|
+
}
|
|
254
|
+
params.push(noteId);
|
|
255
|
+
db.prepare(`UPDATE semantic_notes SET ${setClauses.join(", ")} WHERE note_id = ?`).run(...params);
|
|
256
|
+
}
|
|
257
|
+
export function supersedeNote(db, oldNoteId, newNote) {
|
|
258
|
+
// Inherit thread_id from the old note being superseded
|
|
259
|
+
const oldRow = db.prepare(`SELECT thread_id FROM semantic_notes WHERE note_id = ?`).get(oldNoteId);
|
|
260
|
+
const newId = saveSemanticNote(db, {
|
|
261
|
+
type: newNote.type,
|
|
262
|
+
content: newNote.content,
|
|
263
|
+
keywords: newNote.keywords,
|
|
264
|
+
confidence: newNote.confidence,
|
|
265
|
+
priority: newNote.priority,
|
|
266
|
+
threadId: oldRow?.thread_id ?? null,
|
|
267
|
+
sourceEpisodes: newNote.sourceEpisodes,
|
|
268
|
+
});
|
|
269
|
+
const now = nowISO();
|
|
270
|
+
db.prepare(`UPDATE semantic_notes SET superseded_by = ?, valid_to = ?, updated_at = ? WHERE note_id = ?`).run(newId, now, now, oldNoteId);
|
|
271
|
+
// Create bidirectional link: add old note to new note's linked_notes
|
|
272
|
+
const newRow = db.prepare(`SELECT linked_notes, link_reasons FROM semantic_notes WHERE note_id = ?`).get(newId);
|
|
273
|
+
const currentLinked = parseJsonArray(newRow?.linked_notes);
|
|
274
|
+
const currentReasons = parseJsonObject(newRow?.link_reasons);
|
|
275
|
+
if (!currentLinked.includes(oldNoteId)) {
|
|
276
|
+
currentLinked.push(oldNoteId);
|
|
277
|
+
}
|
|
278
|
+
currentReasons[oldNoteId] = "supersedes";
|
|
279
|
+
updateSemanticNote(db, newId, {
|
|
280
|
+
linkedNotes: currentLinked,
|
|
281
|
+
linkReasons: currentReasons,
|
|
282
|
+
});
|
|
283
|
+
return newId;
|
|
284
|
+
}
|
|
285
|
+
// ─── Embedding-based Semantic Search ─────────────────────────────────────────
|
|
286
|
+
/** Store a pre-computed embedding vector for a semantic note. */
|
|
287
|
+
export function saveNoteEmbedding(db, noteId, embedding) {
|
|
288
|
+
const buf = Buffer.from(embedding.buffer, embedding.byteOffset, embedding.byteLength);
|
|
289
|
+
db.prepare(`INSERT OR REPLACE INTO note_embeddings (note_id, embedding, model, created_at) VALUES (?, ?, ?, ?)`).run(noteId, buf, "text-embedding-3-small", nowISO());
|
|
290
|
+
}
|
|
291
|
+
/** Load all note embeddings into memory for cosine similarity search. */
|
|
292
|
+
function loadAllEmbeddings(db, threadId) {
|
|
293
|
+
// When threadId is provided, return embeddings for notes in that thread OR global notes (thread_id IS NULL)
|
|
294
|
+
let sql = `SELECT ne.note_id, ne.embedding FROM note_embeddings ne
|
|
295
|
+
JOIN semantic_notes sn ON sn.note_id = ne.note_id
|
|
296
|
+
WHERE sn.valid_to IS NULL AND sn.superseded_by IS NULL`;
|
|
297
|
+
const params = [];
|
|
298
|
+
if (threadId !== undefined) {
|
|
299
|
+
sql += ` AND (sn.thread_id IS NULL OR sn.thread_id = ?)`;
|
|
300
|
+
params.push(threadId);
|
|
301
|
+
}
|
|
302
|
+
const rows = db.prepare(sql).all(...params);
|
|
303
|
+
const map = new Map();
|
|
304
|
+
for (const row of rows) {
|
|
305
|
+
map.set(row.note_id, new Float32Array(row.embedding.buffer, row.embedding.byteOffset, row.embedding.byteLength / 4));
|
|
306
|
+
}
|
|
307
|
+
return map;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Search semantic notes using embedding cosine similarity.
|
|
311
|
+
* Returns notes sorted by similarity score, filtered by minimum threshold.
|
|
312
|
+
*/
|
|
313
|
+
export function searchByEmbedding(db, queryEmbedding, options) {
|
|
314
|
+
const maxResults = options?.maxResults ?? 5;
|
|
315
|
+
const minSimilarity = options?.minSimilarity ?? 0.3;
|
|
316
|
+
// Load embeddings — filtered by thread when provided
|
|
317
|
+
const embeddings = loadAllEmbeddings(db, options?.threadId);
|
|
318
|
+
// Compute similarities
|
|
319
|
+
const scores = [];
|
|
320
|
+
for (const [noteId, emb] of embeddings) {
|
|
321
|
+
const sim = cosineSimilarity(queryEmbedding, emb);
|
|
322
|
+
if (sim >= minSimilarity) {
|
|
323
|
+
scores.push({ noteId, similarity: sim });
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
// Sort by similarity descending
|
|
327
|
+
scores.sort((a, b) => b.similarity - a.similarity);
|
|
328
|
+
const topIds = scores.slice(0, maxResults);
|
|
329
|
+
if (topIds.length === 0)
|
|
330
|
+
return [];
|
|
331
|
+
// Fetch full notes
|
|
332
|
+
const placeholders = topIds.map(() => "?").join(",");
|
|
333
|
+
const rows = db.prepare(`SELECT * FROM semantic_notes WHERE note_id IN (${placeholders})`).all(...topIds.map(s => s.noteId));
|
|
334
|
+
const noteMap = new Map();
|
|
335
|
+
for (const row of rows) {
|
|
336
|
+
const note = rowToSemanticNote(row);
|
|
337
|
+
noteMap.set(note.noteId, note);
|
|
338
|
+
}
|
|
339
|
+
// Update access counts
|
|
340
|
+
if (!options?.skipAccessTracking) {
|
|
341
|
+
const now = nowISO();
|
|
342
|
+
const updateStmt = db.prepare(`UPDATE semantic_notes SET access_count = access_count + 1, last_accessed = ? WHERE note_id = ?`);
|
|
343
|
+
db.transaction(() => {
|
|
344
|
+
for (const s of topIds)
|
|
345
|
+
updateStmt.run(now, s.noteId);
|
|
346
|
+
})();
|
|
347
|
+
}
|
|
348
|
+
// Return in similarity order
|
|
349
|
+
return topIds
|
|
350
|
+
.map(s => {
|
|
351
|
+
const note = noteMap.get(s.noteId);
|
|
352
|
+
return note ? { ...note, similarity: s.similarity } : null;
|
|
353
|
+
})
|
|
354
|
+
.filter((n) => n !== null);
|
|
355
|
+
}
|
|
356
|
+
/** Get note IDs that don't have embeddings yet (for backfill). */
|
|
357
|
+
export function getNotesWithoutEmbeddings(db) {
|
|
358
|
+
return db.prepare(`SELECT sn.note_id as noteId, sn.content FROM semantic_notes sn
|
|
359
|
+
LEFT JOIN note_embeddings ne ON ne.note_id = sn.note_id
|
|
360
|
+
WHERE ne.note_id IS NULL AND sn.valid_to IS NULL AND sn.superseded_by IS NULL`).all();
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Find semantic notes that potentially conflict with a given note
|
|
364
|
+
* by sharing >= 2 keywords of the same type.
|
|
365
|
+
*/
|
|
366
|
+
export function findPotentialConflicts(db, noteId) {
|
|
367
|
+
const row = db.prepare(`SELECT note_id, type, keywords FROM semantic_notes WHERE note_id = ?`).get(noteId);
|
|
368
|
+
if (!row)
|
|
369
|
+
return [];
|
|
370
|
+
const noteKeywords = row.keywords ? JSON.parse(row.keywords) : [];
|
|
371
|
+
if (noteKeywords.length < 2)
|
|
372
|
+
return [];
|
|
373
|
+
// Fetch all active notes of the same type (excluding this note and superseded ones)
|
|
374
|
+
const candidates = db.prepare(`SELECT * FROM semantic_notes
|
|
375
|
+
WHERE type = ? AND note_id != ? AND valid_to IS NULL AND superseded_by IS NULL`).all(row.type, noteId);
|
|
376
|
+
const lowerKeywords = new Set(noteKeywords.map(k => k.toLowerCase()));
|
|
377
|
+
return candidates
|
|
378
|
+
.filter(c => {
|
|
379
|
+
const cKeywords = c.keywords ? JSON.parse(c.keywords) : [];
|
|
380
|
+
const overlap = cKeywords.filter(k => lowerKeywords.has(k.toLowerCase())).length;
|
|
381
|
+
return overlap >= 2;
|
|
382
|
+
})
|
|
383
|
+
.map(rowToSemanticNote);
|
|
384
|
+
}
|
|
385
|
+
//# sourceMappingURL=semantic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic.js","sourceRoot":"","sources":["../../../src/data/memory/semantic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Database } from "./schema.js";
|
|
2
|
+
export interface VoiceBaseline {
|
|
3
|
+
avgArousal: number | null;
|
|
4
|
+
avgDominance: number | null;
|
|
5
|
+
avgValence: number | null;
|
|
6
|
+
avgSpeechRate: number | null;
|
|
7
|
+
avgMeanPitchHz: number | null;
|
|
8
|
+
avgPitchStdHz: number | null;
|
|
9
|
+
avgJitter: number | null;
|
|
10
|
+
avgShimmer: number | null;
|
|
11
|
+
avgHnrDb: number | null;
|
|
12
|
+
sampleCount: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function saveVoiceSignature(db: Database, sig: {
|
|
15
|
+
episodeId: string;
|
|
16
|
+
emotion?: string;
|
|
17
|
+
arousal?: number;
|
|
18
|
+
dominance?: number;
|
|
19
|
+
valence?: number;
|
|
20
|
+
speechRate?: number;
|
|
21
|
+
meanPitchHz?: number;
|
|
22
|
+
pitchStdHz?: number;
|
|
23
|
+
jitter?: number;
|
|
24
|
+
shimmer?: number;
|
|
25
|
+
hnrDb?: number;
|
|
26
|
+
audioEvents?: Array<{
|
|
27
|
+
label: string;
|
|
28
|
+
confidence: number;
|
|
29
|
+
}>;
|
|
30
|
+
durationSec?: number;
|
|
31
|
+
}): void;
|
|
32
|
+
export declare function getVoiceBaseline(db: Database, dayRange?: number): VoiceBaseline | null;
|
|
33
|
+
//# sourceMappingURL=voice-sig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-sig.d.ts","sourceRoot":"","sources":["../../../src/data/memory/voice-sig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAI5C,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;CACrB;AAeD,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,QAAQ,EACZ,GAAG,EAAE;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACA,IAAI,CAqBN;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,SAAK,GAAG,aAAa,GAAG,IAAI,CAmClF"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
2
|
+
function nowISO() {
|
|
3
|
+
return new Date().toISOString();
|
|
4
|
+
}
|
|
5
|
+
function jsonOrNull(val) {
|
|
6
|
+
if (val === undefined || val === null)
|
|
7
|
+
return null;
|
|
8
|
+
return JSON.stringify(val);
|
|
9
|
+
}
|
|
10
|
+
// ─── Voice Signatures ────────────────────────────────────────────────────────
|
|
11
|
+
export function saveVoiceSignature(db, sig) {
|
|
12
|
+
db.prepare(`INSERT INTO voice_signatures
|
|
13
|
+
(episode_id, emotion, arousal, dominance, valence, speech_rate, mean_pitch_hz, pitch_std_hz, jitter, shimmer, hnr_db, audio_events, duration_sec, created_at)
|
|
14
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(sig.episodeId, sig.emotion ?? null, sig.arousal ?? null, sig.dominance ?? null, sig.valence ?? null, sig.speechRate ?? null, sig.meanPitchHz ?? null, sig.pitchStdHz ?? null, sig.jitter ?? null, sig.shimmer ?? null, sig.hnrDb ?? null, jsonOrNull(sig.audioEvents), sig.durationSec ?? null, nowISO());
|
|
15
|
+
}
|
|
16
|
+
export function getVoiceBaseline(db, dayRange = 30) {
|
|
17
|
+
const cutoff = new Date(Date.now() - dayRange * 24 * 60 * 60 * 1000).toISOString();
|
|
18
|
+
const row = db
|
|
19
|
+
.prepare(`SELECT
|
|
20
|
+
AVG(arousal) AS avg_arousal,
|
|
21
|
+
AVG(dominance) AS avg_dominance,
|
|
22
|
+
AVG(valence) AS avg_valence,
|
|
23
|
+
AVG(speech_rate) AS avg_speech_rate,
|
|
24
|
+
AVG(mean_pitch_hz) AS avg_mean_pitch_hz,
|
|
25
|
+
AVG(pitch_std_hz) AS avg_pitch_std_hz,
|
|
26
|
+
AVG(jitter) AS avg_jitter,
|
|
27
|
+
AVG(shimmer) AS avg_shimmer,
|
|
28
|
+
AVG(hnr_db) AS avg_hnr_db,
|
|
29
|
+
COUNT(*) AS sample_count
|
|
30
|
+
FROM voice_signatures
|
|
31
|
+
WHERE created_at >= ?`)
|
|
32
|
+
.get(cutoff);
|
|
33
|
+
if (!row || row.sample_count === 0)
|
|
34
|
+
return null;
|
|
35
|
+
return {
|
|
36
|
+
avgArousal: row.avg_arousal,
|
|
37
|
+
avgDominance: row.avg_dominance,
|
|
38
|
+
avgValence: row.avg_valence,
|
|
39
|
+
avgSpeechRate: row.avg_speech_rate,
|
|
40
|
+
avgMeanPitchHz: row.avg_mean_pitch_hz,
|
|
41
|
+
avgPitchStdHz: row.avg_pitch_std_hz,
|
|
42
|
+
avgJitter: row.avg_jitter,
|
|
43
|
+
avgShimmer: row.avg_shimmer,
|
|
44
|
+
avgHnrDb: row.avg_hnr_db,
|
|
45
|
+
sampleCount: row.sample_count,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=voice-sig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-sig.js","sourceRoot":"","sources":["../../../src/data/memory/voice-sig.ts"],"names":[],"mappings":"AAiBA,gFAAgF;AAEhF,SAAS,MAAM;IACb,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC;AAED,SAAS,UAAU,CAAC,GAAY;IAC9B,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACnD,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED,gFAAgF;AAEhF,MAAM,UAAU,kBAAkB,CAChC,EAAY,EACZ,GAcC;IAED,EAAE,CAAC,OAAO,CACR;;uDAEmD,CACpD,CAAC,GAAG,CACH,GAAG,CAAC,SAAS,EACb,GAAG,CAAC,OAAO,IAAI,IAAI,EACnB,GAAG,CAAC,OAAO,IAAI,IAAI,EACnB,GAAG,CAAC,SAAS,IAAI,IAAI,EACrB,GAAG,CAAC,OAAO,IAAI,IAAI,EACnB,GAAG,CAAC,UAAU,IAAI,IAAI,EACtB,GAAG,CAAC,WAAW,IAAI,IAAI,EACvB,GAAG,CAAC,UAAU,IAAI,IAAI,EACtB,GAAG,CAAC,MAAM,IAAI,IAAI,EAClB,GAAG,CAAC,OAAO,IAAI,IAAI,EACnB,GAAG,CAAC,KAAK,IAAI,IAAI,EACjB,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,EAC3B,GAAG,CAAC,WAAW,IAAI,IAAI,EACvB,MAAM,EAAE,CACT,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,EAAY,EAAE,QAAQ,GAAG,EAAE;IAC1D,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAEnF,MAAM,GAAG,GAAG,EAAE;SACX,OAAO,CACN;;;;;;;;;;;;6BAYuB,CACxB;SACA,GAAG,CAAC,MAAM,CAAwC,CAAC;IAEtD,IAAI,CAAC,GAAG,IAAK,GAAG,CAAC,YAAuB,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE5D,OAAO;QACL,UAAU,EAAE,GAAG,CAAC,WAA4B;QAC5C,YAAY,EAAE,GAAG,CAAC,aAA8B;QAChD,UAAU,EAAE,GAAG,CAAC,WAA4B;QAC5C,aAAa,EAAE,GAAG,CAAC,eAAgC;QACnD,cAAc,EAAE,GAAG,CAAC,iBAAkC;QACtD,aAAa,EAAE,GAAG,CAAC,gBAAiC;QACpD,SAAS,EAAE,GAAG,CAAC,UAA2B;QAC1C,UAAU,EAAE,GAAG,CAAC,WAA4B;QAC5C,QAAQ,EAAE,GAAG,CAAC,UAA2B;QACzC,WAAW,EAAE,GAAG,CAAC,YAAsB;KACxC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template loading, caching, and rendering utilities.
|
|
3
|
+
*
|
|
4
|
+
* Templates live in ~/.remote-copilot-mcp/templates/{name}.md and are
|
|
5
|
+
* cached in-memory with a short TTL so edits take effect quickly without
|
|
6
|
+
* needing a server restart.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Load a template file from ~/.remote-copilot-mcp/templates/{name}.md.
|
|
10
|
+
* Returns the raw template string, or null if the file doesn't exist.
|
|
11
|
+
* Results are cached in memory with a 60-second TTL.
|
|
12
|
+
*/
|
|
13
|
+
export declare function loadTemplate(name: string): string | null;
|
|
14
|
+
/**
|
|
15
|
+
* Replace all `{{VAR}}` placeholders in a template string with the
|
|
16
|
+
* corresponding values from the provided vars map.
|
|
17
|
+
*/
|
|
18
|
+
export declare function renderTemplate(template: string, vars: Record<string, string>): string;
|
|
19
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/data/templates.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAiBH;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkBxD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAIrF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template loading, caching, and rendering utilities.
|
|
3
|
+
*
|
|
4
|
+
* Templates live in ~/.remote-copilot-mcp/templates/{name}.md and are
|
|
5
|
+
* cached in-memory with a short TTL so edits take effect quickly without
|
|
6
|
+
* needing a server restart.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { TEMPLATES_DIR } from "../config.js";
|
|
11
|
+
// ── Template loading & caching ────────────────────────────────────────────
|
|
12
|
+
const TEMPLATE_TTL_MS = 60_000; // 60-second cache TTL
|
|
13
|
+
const templateCache = new Map();
|
|
14
|
+
/**
|
|
15
|
+
* Load a template file from ~/.remote-copilot-mcp/templates/{name}.md.
|
|
16
|
+
* Returns the raw template string, or null if the file doesn't exist.
|
|
17
|
+
* Results are cached in memory with a 60-second TTL.
|
|
18
|
+
*/
|
|
19
|
+
export function loadTemplate(name) {
|
|
20
|
+
const now = Date.now();
|
|
21
|
+
const cached = templateCache.get(name);
|
|
22
|
+
if (cached && now - cached.loadedAt < TEMPLATE_TTL_MS) {
|
|
23
|
+
return cached.content;
|
|
24
|
+
}
|
|
25
|
+
const filePath = join(TEMPLATES_DIR, `${name}.md`);
|
|
26
|
+
let content = null;
|
|
27
|
+
try {
|
|
28
|
+
content = readFileSync(filePath, "utf-8");
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// File doesn't exist or is unreadable — fall back to null
|
|
32
|
+
content = null;
|
|
33
|
+
}
|
|
34
|
+
templateCache.set(name, { content, loadedAt: now });
|
|
35
|
+
return content;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Replace all `{{VAR}}` placeholders in a template string with the
|
|
39
|
+
* corresponding values from the provided vars map.
|
|
40
|
+
*/
|
|
41
|
+
export function renderTemplate(template, vars) {
|
|
42
|
+
return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
|
|
43
|
+
return Object.prototype.hasOwnProperty.call(vars, key) ? vars[key] : match;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/data/templates.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,6EAA6E;AAE7E,MAAM,eAAe,GAAG,MAAM,CAAC,CAAC,sBAAsB;AAOtD,MAAM,aAAa,GAAG,IAAI,GAAG,EAA0B,CAAC;AAExD;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,QAAQ,GAAG,eAAe,EAAE,CAAC;QACtD,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;IACnD,IAAI,OAAO,GAAkB,IAAI,CAAC;IAClC,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,0DAA0D;QAC1D,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;IACpD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,IAA4B;IAC3E,OAAO,QAAQ,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,GAAW,EAAE,EAAE;QAC/D,OAAO,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC7E,CAAC,CAAC,CAAC;AACL,CAAC"}
|