sensorium-mcp 2.16.29 → 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 -1373
- 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 -404
- 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,248 @@
|
|
|
1
|
+
import { getUnconsolidatedEpisodes, markConsolidated } from "./episodes.js";
|
|
2
|
+
import { saveSemanticNote, searchSemanticNotesRanked, supersedeNote, } from "./semantic.js";
|
|
3
|
+
import { log } from "../../logger.js";
|
|
4
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
5
|
+
function nowISO() {
|
|
6
|
+
return new Date().toISOString();
|
|
7
|
+
}
|
|
8
|
+
function logConsolidation(db, entry) {
|
|
9
|
+
db.prepare(`INSERT INTO meta_consolidation_log
|
|
10
|
+
(run_at, episodes_processed, notes_created, duration_ms)
|
|
11
|
+
VALUES (?, ?, ?, ?)`).run(nowISO(), entry.episodesProcessed, entry.notesCreated, entry.durationMs);
|
|
12
|
+
}
|
|
13
|
+
// ─── Intelligent Consolidation ───────────────────────────────────────────────
|
|
14
|
+
// PRIVACY NOTE: This function sends conversation episode excerpts to OpenAI's
|
|
15
|
+
// API for knowledge extraction and consolidation. Operators can disable this
|
|
16
|
+
// by setting the environment variable CONSOLIDATION_ENABLED=false (or "0").
|
|
17
|
+
export async function runIntelligentConsolidation(db, threadId, options) {
|
|
18
|
+
// Opt-out: allow operators to disable consolidation for privacy reasons
|
|
19
|
+
const consolidationEnabled = process.env.CONSOLIDATION_ENABLED;
|
|
20
|
+
if (consolidationEnabled === "false" || consolidationEnabled === "0") {
|
|
21
|
+
return {
|
|
22
|
+
episodesProcessed: 0,
|
|
23
|
+
notesCreated: 0,
|
|
24
|
+
durationMs: 0,
|
|
25
|
+
details: ["Consolidation disabled via CONSOLIDATION_ENABLED env var."],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const startMs = Date.now();
|
|
29
|
+
const maxEpisodes = options?.maxEpisodes ?? 30;
|
|
30
|
+
const dryRun = options?.dryRun ?? false;
|
|
31
|
+
const episodes = getUnconsolidatedEpisodes(db, threadId, maxEpisodes);
|
|
32
|
+
if (episodes.length === 0) {
|
|
33
|
+
return {
|
|
34
|
+
episodesProcessed: 0,
|
|
35
|
+
notesCreated: 0,
|
|
36
|
+
durationMs: Date.now() - startMs,
|
|
37
|
+
details: ["Nothing to consolidate."],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// Format episodes for the prompt
|
|
41
|
+
const episodesText = episodes
|
|
42
|
+
.map((ep, i) => {
|
|
43
|
+
const content = typeof ep.content === "object" && ep.content !== null
|
|
44
|
+
? ep.content.text ?? ep.content.caption ?? JSON.stringify(ep.content)
|
|
45
|
+
: String(ep.content);
|
|
46
|
+
return `[${i + 1}] (${ep.type}/${ep.modality}, ${ep.timestamp}) ${content}`;
|
|
47
|
+
})
|
|
48
|
+
.join("\n");
|
|
49
|
+
// ── Contradiction detection: find existing notes related to these episodes ──
|
|
50
|
+
// Extract keywords from episodes to search for potentially conflicting notes
|
|
51
|
+
const episodeWords = episodesText.toLowerCase()
|
|
52
|
+
.replace(/[^a-z0-9\s]/g, " ")
|
|
53
|
+
.split(/\s+/)
|
|
54
|
+
.filter(w => w.length > 3);
|
|
55
|
+
const wordFreq = new Map();
|
|
56
|
+
const stopWords = new Set(["this", "that", "with", "from", "have", "been", "will", "would", "could", "should", "about", "there", "their", "which", "when", "what", "were", "they", "than", "then", "also", "just", "more", "some", "into", "over", "after", "before", "other", "very", "your", "here"]);
|
|
57
|
+
for (const w of episodeWords) {
|
|
58
|
+
if (!stopWords.has(w))
|
|
59
|
+
wordFreq.set(w, (wordFreq.get(w) ?? 0) + 1);
|
|
60
|
+
}
|
|
61
|
+
const topKeywords = [...wordFreq.entries()]
|
|
62
|
+
.sort((a, b) => b[1] - a[1])
|
|
63
|
+
.slice(0, 12)
|
|
64
|
+
.map(([w]) => w);
|
|
65
|
+
let existingNotesSection = "";
|
|
66
|
+
if (topKeywords.length > 0) {
|
|
67
|
+
try {
|
|
68
|
+
const related = searchSemanticNotesRanked(db, topKeywords.join(" "), {
|
|
69
|
+
maxResults: 15,
|
|
70
|
+
skipAccessTracking: true,
|
|
71
|
+
minMatchRatio: 0.2, // broader recall for contradiction scan
|
|
72
|
+
});
|
|
73
|
+
if (related.length > 0) {
|
|
74
|
+
existingNotesSection = `\n\nExisting memory notes (potentially related):
|
|
75
|
+
${related.map(n => `[${n.noteId}] (${n.type}, conf: ${n.confidence}) ${n.content}`).join("\n")}`;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (_) { /* non-fatal — proceed without existing notes */ }
|
|
79
|
+
}
|
|
80
|
+
const systemPrompt = `You are a memory consolidation agent. Analyze these conversation episodes and extract knowledge that should be remembered across sessions.
|
|
81
|
+
|
|
82
|
+
Episodes:
|
|
83
|
+
${episodesText}${existingNotesSection}
|
|
84
|
+
|
|
85
|
+
Output a JSON object with:
|
|
86
|
+
{
|
|
87
|
+
"notes": [
|
|
88
|
+
{
|
|
89
|
+
"type": "fact" | "preference" | "pattern" | "entity" | "relationship",
|
|
90
|
+
"content": "One clear sentence describing the knowledge",
|
|
91
|
+
"keywords": ["keyword1", "keyword2", "keyword3"],
|
|
92
|
+
"confidence": 0.0-1.0,
|
|
93
|
+
"priority": 0 | 1 | 2
|
|
94
|
+
}
|
|
95
|
+
],
|
|
96
|
+
"supersede": [
|
|
97
|
+
{
|
|
98
|
+
"oldNoteId": "sn_xxx",
|
|
99
|
+
"reason": "Why the old note is outdated/contradicted",
|
|
100
|
+
"newContent": "Updated version of the knowledge",
|
|
101
|
+
"type": "fact",
|
|
102
|
+
"keywords": ["keyword1", "keyword2"],
|
|
103
|
+
"confidence": 0.8,
|
|
104
|
+
"priority": 0 | 1 | 2
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
Rules:
|
|
110
|
+
- Only extract information that would be useful in future sessions
|
|
111
|
+
- Preferences are stronger signals than facts (confidence: 0.9)
|
|
112
|
+
- Do not extract trivial/transient information
|
|
113
|
+
- If the operator corrected the agent, extract the correction as a preference
|
|
114
|
+
- Focus on: operator name, preferences, communication style, technical choices, project context
|
|
115
|
+
- CRITICAL: Check existing notes for CONTRADICTIONS. If a new episode contradicts or updates an existing note, add a "supersede" entry. The new episodes represent MORE RECENT information.
|
|
116
|
+
- Common contradictions: decisions changed, projects completed/abandoned, preferences updated, tools/tech switched
|
|
117
|
+
- PRIORITY DETECTION: Infer priority from the operator's language and emotional investment:
|
|
118
|
+
- priority 2 (high importance): operator says "important", "crucial", "I really need", "don't forget", shows strong emotional investment, repeated emphasis
|
|
119
|
+
- priority 1 (notable): operator says "would be nice", "I'd like", "should", mentions something multiple times across conversations
|
|
120
|
+
- priority 0 (normal): default for routine facts, observations, patterns
|
|
121
|
+
- Return {"notes": [], "supersede": []} if nothing notable`;
|
|
122
|
+
let notesCreated = 0;
|
|
123
|
+
const details = [];
|
|
124
|
+
try {
|
|
125
|
+
const apiKey = process.env.OPENAI_API_KEY;
|
|
126
|
+
if (!apiKey) {
|
|
127
|
+
throw new Error("OPENAI_API_KEY not set");
|
|
128
|
+
}
|
|
129
|
+
const controller = new AbortController();
|
|
130
|
+
const timer = setTimeout(() => controller.abort(), 60_000);
|
|
131
|
+
try {
|
|
132
|
+
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
133
|
+
method: "POST",
|
|
134
|
+
headers: {
|
|
135
|
+
"Content-Type": "application/json",
|
|
136
|
+
Authorization: `Bearer ${apiKey}`,
|
|
137
|
+
},
|
|
138
|
+
body: JSON.stringify({
|
|
139
|
+
model: process.env.CONSOLIDATION_MODEL ?? "gpt-4o-mini",
|
|
140
|
+
messages: [
|
|
141
|
+
{ role: "system", content: systemPrompt },
|
|
142
|
+
{ role: "user", content: "Extract knowledge from the episodes above." },
|
|
143
|
+
],
|
|
144
|
+
response_format: { type: "json_object" },
|
|
145
|
+
}),
|
|
146
|
+
signal: controller.signal,
|
|
147
|
+
});
|
|
148
|
+
clearTimeout(timer);
|
|
149
|
+
if (!response.ok) {
|
|
150
|
+
const errText = await response.text().catch(() => response.statusText);
|
|
151
|
+
throw new Error(`OpenAI API error: ${response.status} ${errText}`);
|
|
152
|
+
}
|
|
153
|
+
const result = (await response.json());
|
|
154
|
+
const raw = result.choices?.[0]?.message?.content ?? "{}";
|
|
155
|
+
const parsed = JSON.parse(raw);
|
|
156
|
+
const extractedNotes = parsed.notes ?? [];
|
|
157
|
+
const supersedeActions = parsed.supersede ?? [];
|
|
158
|
+
const episodeIds = episodes.map((ep) => ep.episodeId);
|
|
159
|
+
if (!dryRun) {
|
|
160
|
+
for (const note of extractedNotes) {
|
|
161
|
+
const validTypes = ["fact", "preference", "pattern", "entity", "relationship"];
|
|
162
|
+
const noteType = validTypes.includes(note.type)
|
|
163
|
+
? note.type
|
|
164
|
+
: "fact";
|
|
165
|
+
saveSemanticNote(db, {
|
|
166
|
+
type: noteType,
|
|
167
|
+
content: note.content,
|
|
168
|
+
keywords: Array.isArray(note.keywords) ? note.keywords : [],
|
|
169
|
+
confidence: Math.max(0, Math.min(1, note.confidence ?? 0.5)),
|
|
170
|
+
priority: Math.max(0, Math.min(2, note.priority ?? 0)),
|
|
171
|
+
threadId: threadId,
|
|
172
|
+
sourceEpisodes: episodeIds,
|
|
173
|
+
});
|
|
174
|
+
notesCreated++;
|
|
175
|
+
details.push(`[${noteType}] ${note.content}`);
|
|
176
|
+
}
|
|
177
|
+
// Execute supersede actions — resolve contradictions with existing notes
|
|
178
|
+
let supersededCount = 0;
|
|
179
|
+
for (const action of supersedeActions) {
|
|
180
|
+
if (!action.oldNoteId || !action.newContent)
|
|
181
|
+
continue;
|
|
182
|
+
// Verify old note exists and is still active
|
|
183
|
+
const oldNote = db.prepare(`SELECT note_id FROM semantic_notes WHERE note_id = ? AND valid_to IS NULL AND superseded_by IS NULL`).get(action.oldNoteId);
|
|
184
|
+
if (!oldNote) {
|
|
185
|
+
details.push(`[skip-supersede] ${action.oldNoteId} not found or already superseded`);
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
try {
|
|
189
|
+
const validTypes = ["fact", "preference", "pattern", "entity", "relationship"];
|
|
190
|
+
const noteType = validTypes.includes(action.type) ? action.type : "fact";
|
|
191
|
+
const newId = supersedeNote(db, action.oldNoteId, {
|
|
192
|
+
type: noteType,
|
|
193
|
+
content: action.newContent,
|
|
194
|
+
keywords: Array.isArray(action.keywords) ? action.keywords : [],
|
|
195
|
+
confidence: Math.max(0, Math.min(1, action.confidence ?? 0.8)),
|
|
196
|
+
priority: Math.max(0, Math.min(2, action.priority ?? 0)),
|
|
197
|
+
sourceEpisodes: episodeIds,
|
|
198
|
+
});
|
|
199
|
+
supersededCount++;
|
|
200
|
+
details.push(`[supersede] ${action.oldNoteId} → ${newId}: ${action.reason}`);
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
details.push(`[supersede-error] ${action.oldNoteId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (supersededCount > 0) {
|
|
207
|
+
log.info(`[memory] Contradiction resolution: superseded ${supersededCount} outdated note(s)`);
|
|
208
|
+
}
|
|
209
|
+
// Mark episodes as consolidated
|
|
210
|
+
markConsolidated(db, episodeIds);
|
|
211
|
+
// Log the consolidation
|
|
212
|
+
logConsolidation(db, {
|
|
213
|
+
episodesProcessed: episodes.length,
|
|
214
|
+
notesCreated: notesCreated + supersededCount,
|
|
215
|
+
durationMs: Date.now() - startMs,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
for (const note of extractedNotes) {
|
|
220
|
+
details.push(`[dry-run] [${note.type}] ${note.content}`);
|
|
221
|
+
notesCreated++;
|
|
222
|
+
}
|
|
223
|
+
for (const action of supersedeActions) {
|
|
224
|
+
details.push(`[dry-run] [supersede] ${action.oldNoteId} → ${action.reason}`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
finally {
|
|
229
|
+
clearTimeout(timer);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
// Do NOT mark episodes as consolidated on failure — they should be
|
|
234
|
+
// retried on the next consolidation run. Previously this was a silent
|
|
235
|
+
// data-loss bug: a transient OpenAI outage would permanently lose the
|
|
236
|
+
// episodes' knowledge without extracting anything.
|
|
237
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
238
|
+
log.error(`[memory] Intelligent consolidation failed (episodes NOT marked): ${msg}`);
|
|
239
|
+
details.push(`Consolidation failed (will retry): ${msg}`);
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
episodesProcessed: episodes.length,
|
|
243
|
+
notesCreated,
|
|
244
|
+
durationMs: Date.now() - startMs,
|
|
245
|
+
details,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=consolidation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidation.js","sourceRoot":"","sources":["../../../src/data/memory/consolidation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Episode CRUD operations for the memory system.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from memory.ts — episodic memory layer.
|
|
5
|
+
*/
|
|
6
|
+
import type { Database } from "./schema.js";
|
|
7
|
+
export interface Episode {
|
|
8
|
+
episodeId: string;
|
|
9
|
+
sessionId: string;
|
|
10
|
+
threadId: number;
|
|
11
|
+
timestamp: string;
|
|
12
|
+
type: "operator_message" | "agent_action" | "system_event" | "operator_reaction";
|
|
13
|
+
modality: "text" | "voice" | "photo" | "video_note" | "document" | "mixed" | "reaction";
|
|
14
|
+
content: Record<string, unknown>;
|
|
15
|
+
topicTags: string[];
|
|
16
|
+
importance: number;
|
|
17
|
+
consolidated: boolean;
|
|
18
|
+
accessedCount: number;
|
|
19
|
+
lastAccessed: string | null;
|
|
20
|
+
createdAt: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function saveEpisode(db: Database, episode: {
|
|
23
|
+
sessionId: string;
|
|
24
|
+
threadId: number;
|
|
25
|
+
type: "operator_message" | "agent_action" | "system_event" | "operator_reaction";
|
|
26
|
+
modality: "text" | "voice" | "photo" | "video_note" | "document" | "mixed" | "reaction";
|
|
27
|
+
content: Record<string, unknown>;
|
|
28
|
+
topicTags?: string[];
|
|
29
|
+
importance?: number;
|
|
30
|
+
}): string;
|
|
31
|
+
export declare function getRecentEpisodes(db: Database, threadId: number, limit?: number): Episode[];
|
|
32
|
+
export declare function getUnconsolidatedEpisodes(db: Database, threadId: number, limit?: number): Episode[];
|
|
33
|
+
export declare function markConsolidated(db: Database, episodeIds: string[]): void;
|
|
34
|
+
//# sourceMappingURL=episodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"episodes.d.ts","sourceRoot":"","sources":["../../../src/data/memory/episodes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAI5C,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,kBAAkB,GAAG,cAAc,GAAG,cAAc,GAAG,mBAAmB,CAAC;IACjF,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,YAAY,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;IACxF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB;AAyDD,wBAAgB,WAAW,CACzB,EAAE,EAAE,QAAQ,EACZ,OAAO,EAAE;IACP,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,kBAAkB,GAAG,cAAc,GAAG,cAAc,GAAG,mBAAmB,CAAC;IACjF,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,YAAY,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;IACxF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GACA,MAAM,CAsBR;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,EAAE,CAOvF;AAED,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,EAAE,CAO/F;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI,CASzE"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Episode CRUD operations for the memory system.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from memory.ts — episodic memory layer.
|
|
5
|
+
*/
|
|
6
|
+
import { randomUUID } from "crypto";
|
|
7
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
8
|
+
function generateId(prefix) {
|
|
9
|
+
return `${prefix}_${randomUUID().replace(/-/g, "").slice(0, 12)}`;
|
|
10
|
+
}
|
|
11
|
+
function nowISO() {
|
|
12
|
+
return new Date().toISOString();
|
|
13
|
+
}
|
|
14
|
+
function jsonOrNull(val) {
|
|
15
|
+
if (val === undefined || val === null)
|
|
16
|
+
return null;
|
|
17
|
+
return JSON.stringify(val);
|
|
18
|
+
}
|
|
19
|
+
function parseJsonArray(val) {
|
|
20
|
+
if (!val)
|
|
21
|
+
return [];
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(val);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function parseJsonObject(val) {
|
|
30
|
+
if (!val)
|
|
31
|
+
return {};
|
|
32
|
+
try {
|
|
33
|
+
return JSON.parse(val);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// ─── Row → Interface mapper ─────────────────────────────────────────────────
|
|
40
|
+
function rowToEpisode(row) {
|
|
41
|
+
return {
|
|
42
|
+
episodeId: row.episode_id,
|
|
43
|
+
sessionId: row.session_id,
|
|
44
|
+
threadId: row.thread_id,
|
|
45
|
+
timestamp: row.timestamp,
|
|
46
|
+
type: row.type,
|
|
47
|
+
modality: row.modality,
|
|
48
|
+
content: parseJsonObject(row.content),
|
|
49
|
+
topicTags: parseJsonArray(row.topic_tags),
|
|
50
|
+
importance: row.importance,
|
|
51
|
+
consolidated: row.consolidated === 1,
|
|
52
|
+
accessedCount: row.accessed_count,
|
|
53
|
+
lastAccessed: row.last_accessed ?? null,
|
|
54
|
+
createdAt: row.created_at,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
// ─── Episodic Memory CRUD ────────────────────────────────────────────────────
|
|
58
|
+
export function saveEpisode(db, episode) {
|
|
59
|
+
const id = generateId("ep");
|
|
60
|
+
const now = nowISO();
|
|
61
|
+
db.prepare(`INSERT INTO episodes
|
|
62
|
+
(episode_id, session_id, thread_id, timestamp, type, modality, content, topic_tags, importance, consolidated, accessed_count, created_at)
|
|
63
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 0, 0, ?)`).run(id, episode.sessionId, episode.threadId, now, episode.type, episode.modality, JSON.stringify(episode.content), jsonOrNull(episode.topicTags), episode.importance ?? 0.5, now);
|
|
64
|
+
return id;
|
|
65
|
+
}
|
|
66
|
+
export function getRecentEpisodes(db, threadId, limit = 20) {
|
|
67
|
+
const rows = db
|
|
68
|
+
.prepare(`SELECT * FROM episodes WHERE thread_id = ? ORDER BY timestamp DESC LIMIT ?`)
|
|
69
|
+
.all(threadId, limit);
|
|
70
|
+
return rows.map(rowToEpisode);
|
|
71
|
+
}
|
|
72
|
+
export function getUnconsolidatedEpisodes(db, threadId, limit = 50) {
|
|
73
|
+
const rows = db
|
|
74
|
+
.prepare(`SELECT * FROM episodes WHERE thread_id = ? AND consolidated = 0 ORDER BY timestamp ASC LIMIT ?`)
|
|
75
|
+
.all(threadId, limit);
|
|
76
|
+
return rows.map(rowToEpisode);
|
|
77
|
+
}
|
|
78
|
+
export function markConsolidated(db, episodeIds) {
|
|
79
|
+
if (episodeIds.length === 0)
|
|
80
|
+
return;
|
|
81
|
+
const stmt = db.prepare(`UPDATE episodes SET consolidated = 1 WHERE episode_id = ?`);
|
|
82
|
+
const txn = db.transaction(() => {
|
|
83
|
+
for (const id of episodeIds) {
|
|
84
|
+
stmt.run(id);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
txn();
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=episodes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"episodes.js","sourceRoot":"","sources":["../../../src/data/memory/episodes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Barrel re-export for the memory subsystem.
|
|
3
|
+
*
|
|
4
|
+
* All memory modules are re-exported here so consumers can import from
|
|
5
|
+
* a single path: `./data/memory/index.js`.
|
|
6
|
+
*/
|
|
7
|
+
export * from './schema.js';
|
|
8
|
+
export * from './episodes.js';
|
|
9
|
+
export * from './semantic.js';
|
|
10
|
+
export * from './procedures.js';
|
|
11
|
+
export * from './voice-sig.js';
|
|
12
|
+
export * from './consolidation.js';
|
|
13
|
+
export * from './bootstrap.js';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/data/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Barrel re-export for the memory subsystem.
|
|
3
|
+
*
|
|
4
|
+
* All memory modules are re-exported here so consumers can import from
|
|
5
|
+
* a single path: `./data/memory/index.js`.
|
|
6
|
+
*/
|
|
7
|
+
export * from './schema.js';
|
|
8
|
+
export * from './episodes.js';
|
|
9
|
+
export * from './semantic.js';
|
|
10
|
+
export * from './procedures.js';
|
|
11
|
+
export * from './voice-sig.js';
|
|
12
|
+
export * from './consolidation.js';
|
|
13
|
+
export * from './bootstrap.js';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/data/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Procedure CRUD operations for the memory system.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from memory.ts — procedural memory layer.
|
|
5
|
+
*/
|
|
6
|
+
import type { Database } from "./schema.js";
|
|
7
|
+
export interface Procedure {
|
|
8
|
+
procedureId: string;
|
|
9
|
+
name: string;
|
|
10
|
+
type: "workflow" | "habit" | "tool_pattern" | "template";
|
|
11
|
+
description: string;
|
|
12
|
+
steps: string[];
|
|
13
|
+
triggerConditions: string[];
|
|
14
|
+
successRate: number;
|
|
15
|
+
timesExecuted: number;
|
|
16
|
+
lastExecutedAt: string | null;
|
|
17
|
+
learnedFrom: string[];
|
|
18
|
+
corrections: string[];
|
|
19
|
+
relatedProcedures: string[];
|
|
20
|
+
confidence: number;
|
|
21
|
+
createdAt: string;
|
|
22
|
+
updatedAt: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function rowToProcedure(row: Record<string, unknown>): Procedure;
|
|
25
|
+
export declare function saveProcedure(db: Database, proc: {
|
|
26
|
+
name: string;
|
|
27
|
+
type: "workflow" | "habit" | "tool_pattern" | "template";
|
|
28
|
+
description: string;
|
|
29
|
+
steps?: string[];
|
|
30
|
+
triggerConditions?: string[];
|
|
31
|
+
}): string;
|
|
32
|
+
export declare function searchProcedures(db: Database, query: string, maxResults?: number): Procedure[];
|
|
33
|
+
export declare function updateProcedure(db: Database, procedureId: string, updates: Partial<{
|
|
34
|
+
description: string;
|
|
35
|
+
steps: string[];
|
|
36
|
+
triggerConditions: string[];
|
|
37
|
+
successRate: number;
|
|
38
|
+
timesExecuted: number;
|
|
39
|
+
corrections: string[];
|
|
40
|
+
confidence: number;
|
|
41
|
+
}>): void;
|
|
42
|
+
//# sourceMappingURL=procedures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"procedures.d.ts","sourceRoot":"","sources":["../../../src/data/memory/procedures.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAK5C,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,cAAc,GAAG,UAAU,CAAC;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AA4BD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAkBtE;AAID,wBAAgB,aAAa,CAC3B,EAAE,EAAE,QAAQ,EACZ,IAAI,EAAE;IACJ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,cAAc,GAAG,UAAU,CAAC;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B,GACA,MAAM,CA8BR;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,SAAK,GAAG,SAAS,EAAE,CAsB1F;AAED,wBAAgB,eAAe,CAC7B,EAAE,EAAE,QAAQ,EACZ,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,GACD,IAAI,CAoCN"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Procedure CRUD operations for the memory system.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from memory.ts — procedural memory layer.
|
|
5
|
+
*/
|
|
6
|
+
import { randomUUID } from "crypto";
|
|
7
|
+
import { updateTopicIndexForKeywords } from "./semantic.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
|
+
// ─── Row → Interface mapper ─────────────────────────────────────────────────
|
|
31
|
+
export function rowToProcedure(row) {
|
|
32
|
+
return {
|
|
33
|
+
procedureId: row.procedure_id,
|
|
34
|
+
name: row.name,
|
|
35
|
+
type: row.type,
|
|
36
|
+
description: row.description,
|
|
37
|
+
steps: parseJsonArray(row.steps),
|
|
38
|
+
triggerConditions: parseJsonArray(row.trigger_conditions),
|
|
39
|
+
successRate: row.success_rate,
|
|
40
|
+
timesExecuted: row.times_executed,
|
|
41
|
+
lastExecutedAt: row.last_executed_at ?? null,
|
|
42
|
+
learnedFrom: parseJsonArray(row.learned_from),
|
|
43
|
+
corrections: parseJsonArray(row.corrections),
|
|
44
|
+
relatedProcedures: parseJsonArray(row.related_procedures),
|
|
45
|
+
confidence: row.confidence,
|
|
46
|
+
createdAt: row.created_at,
|
|
47
|
+
updatedAt: row.updated_at,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// ─── Procedural Memory ──────────────────────────────────────────────────────
|
|
51
|
+
export function saveProcedure(db, proc) {
|
|
52
|
+
const id = generateId("pr");
|
|
53
|
+
const now = nowISO();
|
|
54
|
+
db.prepare(`INSERT INTO procedures
|
|
55
|
+
(procedure_id, name, type, description, steps, trigger_conditions, success_rate, times_executed, learned_from, corrections, related_procedures, confidence, created_at, updated_at)
|
|
56
|
+
VALUES (?, ?, ?, ?, ?, ?, 0.5, 0, ?, ?, ?, 0.5, ?, ?)`).run(id, proc.name, proc.type, proc.description, jsonOrNull(proc.steps), jsonOrNull(proc.triggerConditions), null, // learned_from
|
|
57
|
+
null, // corrections
|
|
58
|
+
null, // related_procedures
|
|
59
|
+
now, now);
|
|
60
|
+
// Update topic index based on procedure name words
|
|
61
|
+
const keywords = proc.name
|
|
62
|
+
.toLowerCase()
|
|
63
|
+
.split(/\s+/)
|
|
64
|
+
.filter((w) => w.length > 2);
|
|
65
|
+
updateTopicIndexForKeywords(db, keywords, "procedural");
|
|
66
|
+
return id;
|
|
67
|
+
}
|
|
68
|
+
export function searchProcedures(db, query, maxResults = 10) {
|
|
69
|
+
const terms = query
|
|
70
|
+
.toLowerCase()
|
|
71
|
+
.split(/\s+/)
|
|
72
|
+
.filter((t) => t.length > 1);
|
|
73
|
+
if (terms.length === 0)
|
|
74
|
+
return [];
|
|
75
|
+
const conditions = [];
|
|
76
|
+
const params = [];
|
|
77
|
+
for (const term of terms) {
|
|
78
|
+
const escaped = term.replace(/%/g, "\\%").replace(/_/g, "\\_");
|
|
79
|
+
conditions.push(`(LOWER(name) LIKE ? ESCAPE '\\' OR LOWER(description) LIKE ? ESCAPE '\\' OR LOWER(steps) LIKE ? ESCAPE '\\' OR LOWER(trigger_conditions) LIKE ? ESCAPE '\\')`);
|
|
80
|
+
params.push(`%${escaped}%`, `%${escaped}%`, `%${escaped}%`, `%${escaped}%`);
|
|
81
|
+
}
|
|
82
|
+
const sql = `SELECT * FROM procedures WHERE ${conditions.join(" OR ")} ORDER BY confidence DESC, success_rate DESC LIMIT ?`;
|
|
83
|
+
params.push(maxResults);
|
|
84
|
+
const rows = db.prepare(sql).all(...params);
|
|
85
|
+
return rows.map(rowToProcedure);
|
|
86
|
+
}
|
|
87
|
+
export function updateProcedure(db, procedureId, updates) {
|
|
88
|
+
const now = nowISO();
|
|
89
|
+
const setClauses = ["updated_at = ?"];
|
|
90
|
+
const params = [now];
|
|
91
|
+
if (updates.description !== undefined) {
|
|
92
|
+
setClauses.push("description = ?");
|
|
93
|
+
params.push(updates.description);
|
|
94
|
+
}
|
|
95
|
+
if (updates.steps !== undefined) {
|
|
96
|
+
setClauses.push("steps = ?");
|
|
97
|
+
params.push(JSON.stringify(updates.steps));
|
|
98
|
+
}
|
|
99
|
+
if (updates.triggerConditions !== undefined) {
|
|
100
|
+
setClauses.push("trigger_conditions = ?");
|
|
101
|
+
params.push(JSON.stringify(updates.triggerConditions));
|
|
102
|
+
}
|
|
103
|
+
if (updates.successRate !== undefined) {
|
|
104
|
+
setClauses.push("success_rate = ?");
|
|
105
|
+
params.push(updates.successRate);
|
|
106
|
+
}
|
|
107
|
+
if (updates.timesExecuted !== undefined) {
|
|
108
|
+
setClauses.push("times_executed = ?");
|
|
109
|
+
params.push(updates.timesExecuted);
|
|
110
|
+
}
|
|
111
|
+
if (updates.corrections !== undefined) {
|
|
112
|
+
setClauses.push("corrections = ?");
|
|
113
|
+
params.push(JSON.stringify(updates.corrections));
|
|
114
|
+
}
|
|
115
|
+
if (updates.confidence !== undefined) {
|
|
116
|
+
setClauses.push("confidence = ?");
|
|
117
|
+
params.push(updates.confidence);
|
|
118
|
+
}
|
|
119
|
+
params.push(procedureId);
|
|
120
|
+
db.prepare(`UPDATE procedures SET ${setClauses.join(", ")} WHERE procedure_id = ?`).run(...params);
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=procedures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"procedures.js","sourceRoot":"","sources":["../../../src/data/memory/procedures.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory database schema initialization and migrations.
|
|
3
|
+
*
|
|
4
|
+
* Owns the SQLite `db` handle creation via `initMemoryDb()`.
|
|
5
|
+
* Other memory modules import `Database` (the type) and call
|
|
6
|
+
* `initMemoryDb()` to obtain the singleton handle.
|
|
7
|
+
*/
|
|
8
|
+
import BetterSqlite3 from "better-sqlite3";
|
|
9
|
+
export type Database = BetterSqlite3.Database;
|
|
10
|
+
export declare function initMemoryDb(): Database;
|
|
11
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/data/memory/schema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAO3C,MAAM,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC;AA0Q9C,wBAAgB,YAAY,IAAI,QAAQ,CA+DvC"}
|