sensorium-mcp 2.9.5 → 2.11.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/dist/config.d.ts +12 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +70 -0
- package/dist/config.js.map +1 -0
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/dashboard.js +76 -1
- package/dist/dashboard.js.map +1 -1
- package/dist/drive.d.ts +18 -0
- package/dist/drive.d.ts.map +1 -0
- package/dist/drive.js +234 -0
- package/dist/drive.js.map +1 -0
- package/dist/index.js +203 -952
- package/dist/index.js.map +1 -1
- package/dist/markdown.d.ts +26 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +100 -0
- package/dist/markdown.js.map +1 -0
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +10 -3
- package/dist/memory.js.map +1 -1
- package/dist/rate-limiter.d.ts +95 -0
- package/dist/rate-limiter.d.ts.map +1 -0
- package/dist/rate-limiter.js +311 -0
- package/dist/rate-limiter.js.map +1 -0
- package/dist/sessions.d.ts +23 -0
- package/dist/sessions.d.ts.map +1 -0
- package/dist/sessions.js +83 -0
- package/dist/sessions.js.map +1 -0
- package/dist/tool-definitions.d.ts +15 -0
- package/dist/tool-definitions.d.ts.map +1 -0
- package/dist/tool-definitions.js +432 -0
- package/dist/tool-definitions.js.map +1 -0
- package/dist/types.d.ts +57 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/package.json +1 -1
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized configuration — reads environment variables at startup
|
|
3
|
+
* and exports validated values used throughout the codebase.
|
|
4
|
+
*/
|
|
5
|
+
import type { AppConfig } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Save a buffer to disk under FILES_DIR with a unique timestamped name.
|
|
8
|
+
* Returns the absolute file path. Caps directory at 500 files by deleting oldest.
|
|
9
|
+
*/
|
|
10
|
+
export declare function saveFileToDisk(buffer: Buffer, filename: string): string;
|
|
11
|
+
export declare const config: AppConfig;
|
|
12
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAkC5C;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAqBvE;AAID,eAAO,MAAM,MAAM,EAAE,SAQpB,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized configuration — reads environment variables at startup
|
|
3
|
+
* and exports validated values used throughout the codebase.
|
|
4
|
+
*/
|
|
5
|
+
import { createRequire } from "node:module";
|
|
6
|
+
import { mkdirSync, readdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { homedir } from "node:os";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
const esmRequire = createRequire(import.meta.url);
|
|
10
|
+
const { version: PKG_VERSION } = esmRequire("../package.json");
|
|
11
|
+
// ─── Environment variables ──────────────────────────────────────────────────
|
|
12
|
+
const TELEGRAM_TOKEN = process.env.TELEGRAM_TOKEN ?? "";
|
|
13
|
+
const TELEGRAM_CHAT_ID = process.env.TELEGRAM_CHAT_ID ?? "";
|
|
14
|
+
const OPENAI_API_KEY = process.env.OPENAI_API_KEY ?? "";
|
|
15
|
+
const VOICE_ANALYSIS_URL = process.env.VOICE_ANALYSIS_URL ?? "";
|
|
16
|
+
const rawWaitTimeoutMinutes = parseInt(process.env.WAIT_TIMEOUT_MINUTES ?? "", 10);
|
|
17
|
+
const WAIT_TIMEOUT_MINUTES = Math.max(1, Number.isFinite(rawWaitTimeoutMinutes) ? rawWaitTimeoutMinutes : 120);
|
|
18
|
+
// ─── Validation ─────────────────────────────────────────────────────────────
|
|
19
|
+
if (!TELEGRAM_TOKEN || !TELEGRAM_CHAT_ID) {
|
|
20
|
+
process.stderr.write("Error: TELEGRAM_TOKEN and TELEGRAM_CHAT_ID environment variables are required.\n");
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
if (!OPENAI_API_KEY) {
|
|
24
|
+
process.stderr.write("Warning: OPENAI_API_KEY not set — voice messages will not be transcribed.\n");
|
|
25
|
+
}
|
|
26
|
+
if (VOICE_ANALYSIS_URL) {
|
|
27
|
+
process.stderr.write(`Voice analysis service configured: ${VOICE_ANALYSIS_URL}\n`);
|
|
28
|
+
}
|
|
29
|
+
// ─── File storage ───────────────────────────────────────────────────────────
|
|
30
|
+
const FILES_DIR = join(homedir(), ".remote-copilot-mcp", "files");
|
|
31
|
+
mkdirSync(FILES_DIR, { recursive: true });
|
|
32
|
+
/**
|
|
33
|
+
* Save a buffer to disk under FILES_DIR with a unique timestamped name.
|
|
34
|
+
* Returns the absolute file path. Caps directory at 500 files by deleting oldest.
|
|
35
|
+
*/
|
|
36
|
+
export function saveFileToDisk(buffer, filename) {
|
|
37
|
+
const ts = Date.now();
|
|
38
|
+
const safeName = filename.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
39
|
+
const diskName = `${ts}-${safeName}`;
|
|
40
|
+
const filePath = join(FILES_DIR, diskName);
|
|
41
|
+
writeFileSync(filePath, buffer);
|
|
42
|
+
// Cleanup: cap at 500 files
|
|
43
|
+
try {
|
|
44
|
+
const files = readdirSync(FILES_DIR)
|
|
45
|
+
.map(f => ({ name: f, mtime: statSync(join(FILES_DIR, f)).mtimeMs }))
|
|
46
|
+
.sort((a, b) => a.mtime - b.mtime);
|
|
47
|
+
if (files.length > 500) {
|
|
48
|
+
const toDelete = files.slice(0, files.length - 500);
|
|
49
|
+
for (const f of toDelete) {
|
|
50
|
+
try {
|
|
51
|
+
unlinkSync(join(FILES_DIR, f.name));
|
|
52
|
+
}
|
|
53
|
+
catch (_) { /* ignore */ }
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (_) { /* non-fatal */ }
|
|
58
|
+
return filePath;
|
|
59
|
+
}
|
|
60
|
+
// ─── Exported config object ─────────────────────────────────────────────────
|
|
61
|
+
export const config = {
|
|
62
|
+
TELEGRAM_TOKEN,
|
|
63
|
+
TELEGRAM_CHAT_ID,
|
|
64
|
+
OPENAI_API_KEY,
|
|
65
|
+
VOICE_ANALYSIS_URL,
|
|
66
|
+
WAIT_TIMEOUT_MINUTES,
|
|
67
|
+
FILES_DIR,
|
|
68
|
+
PKG_VERSION,
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/dashboard.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAajE,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,MAAM,QAAQ,CAAC;IACtB,iBAAiB,EAAE,MAAM,KAAK,CAAC;QAC3B,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;KACzB,CAAC,CAAC;IACH,eAAe,EAAE,MAAM,CAAC;CAC3B;AAID;;GAEG;AACH,wBAAgB,sBAAsB,CAClC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,gBAAgB,EACrB,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CA0BT"}
|
package/dist/dashboard.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* The dashboard page itself is served without auth — API token entered in the UI.
|
|
15
15
|
*/
|
|
16
16
|
import { getRecentEpisodes, getTopicIndex, getTopSemanticNotes, searchSemanticNotesRanked } from "./memory.js";
|
|
17
|
+
import { rateLimiter } from "./rate-limiter.js";
|
|
17
18
|
// ─── Route handler ───────────────────────────────────────────────────────────
|
|
18
19
|
/**
|
|
19
20
|
* Handle a dashboard or API request. Returns true if handled, false if not a dashboard route.
|
|
@@ -118,6 +119,10 @@ function handleApiRoute(path, url, res, ctx) {
|
|
|
118
119
|
json(searchSemanticNotesRanked(db, q, { maxResults: parseInt(url.searchParams.get("limit") ?? "20", 10) }));
|
|
119
120
|
return true;
|
|
120
121
|
}
|
|
122
|
+
if (path === "/api/rate-limits") {
|
|
123
|
+
json(rateLimiter.getStats());
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
121
126
|
json({ error: "Not found" }, 404);
|
|
122
127
|
return true;
|
|
123
128
|
}
|
|
@@ -266,6 +271,7 @@ function getDashboardHTML() {
|
|
|
266
271
|
<button onclick="switchTab('notes')" id="tab-notes" class="pb-3 text-sm font-medium tab-inactive transition">Memory Notes</button>
|
|
267
272
|
<button onclick="switchTab('episodes')" id="tab-episodes" class="pb-3 text-sm font-medium tab-inactive transition">Episodes</button>
|
|
268
273
|
<button onclick="switchTab('topics')" id="tab-topics" class="pb-3 text-sm font-medium tab-inactive transition">Topics</button>
|
|
274
|
+
<button onclick="switchTab('ratelimits')" id="tab-ratelimits" class="pb-3 text-sm font-medium tab-inactive transition">Rate Limits</button>
|
|
269
275
|
</nav>
|
|
270
276
|
</div>
|
|
271
277
|
|
|
@@ -315,6 +321,12 @@ function getDashboardHTML() {
|
|
|
315
321
|
<div id="panel-topics" class="hidden animate-fade-in">
|
|
316
322
|
<div id="topics-grid" class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3"></div>
|
|
317
323
|
</div>
|
|
324
|
+
|
|
325
|
+
<!-- Rate Limits -->
|
|
326
|
+
<div id="panel-ratelimits" class="hidden animate-fade-in">
|
|
327
|
+
<div id="ratelimits-summary" class="mb-4 glass rounded-xl p-4"></div>
|
|
328
|
+
<div id="ratelimits-grid" class="grid grid-cols-1 sm:grid-cols-2 gap-3"></div>
|
|
329
|
+
</div>
|
|
318
330
|
</div>
|
|
319
331
|
</div>
|
|
320
332
|
|
|
@@ -534,9 +546,64 @@ function getDashboardHTML() {
|
|
|
534
546
|
}).join('');
|
|
535
547
|
}
|
|
536
548
|
|
|
549
|
+
function renderRateLimits(data) {
|
|
550
|
+
const summary = document.getElementById('ratelimits-summary');
|
|
551
|
+
const grid = document.getElementById('ratelimits-grid');
|
|
552
|
+
summary.innerHTML =
|
|
553
|
+
'<div class="flex items-center justify-between">' +
|
|
554
|
+
'<div>' +
|
|
555
|
+
'<div class="text-sm text-textSecondary">Active Agents Sharing Resources</div>' +
|
|
556
|
+
'<div class="text-3xl font-bold font-mono text-accent">' + data.activeSessions + '</div>' +
|
|
557
|
+
'</div>' +
|
|
558
|
+
'<div class="text-right">' +
|
|
559
|
+
'<div class="text-sm text-textSecondary">Total Calls (Last Hour)</div>' +
|
|
560
|
+
'<div class="text-3xl font-bold font-mono">' + data.totalCallsLastHour + '</div>' +
|
|
561
|
+
'</div>' +
|
|
562
|
+
'</div>';
|
|
563
|
+
if (!data.services || !data.services.length) {
|
|
564
|
+
grid.innerHTML = '<p class="text-textSecondary col-span-full text-center py-8">No services tracked yet</p>';
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
grid.innerHTML = data.services.map(function(svc) {
|
|
568
|
+
var pct = svc.usagePercent;
|
|
569
|
+
var barColor = pct > 80 ? 'danger' : pct > 50 ? 'warn' : 'success';
|
|
570
|
+
var breakdown = '';
|
|
571
|
+
if (svc.sessionBreakdown && svc.sessionBreakdown.length > 0) {
|
|
572
|
+
breakdown = '<div class="mt-3 space-y-1">' +
|
|
573
|
+
'<div class="text-xs text-textSecondary font-medium uppercase tracking-wider">Per-Session Breakdown</div>' +
|
|
574
|
+
svc.sessionBreakdown.map(function(s) {
|
|
575
|
+
return '<div class="flex items-center justify-between text-xs">' +
|
|
576
|
+
'<span class="text-textSecondary font-mono">Thread ' + (s.threadId || '?') + '</span>' +
|
|
577
|
+
'<span class="font-mono text-textPrimary">' + s.calls + ' calls</span>' +
|
|
578
|
+
'</div>';
|
|
579
|
+
}).join('') +
|
|
580
|
+
'</div>';
|
|
581
|
+
}
|
|
582
|
+
return '<div class="glass rounded-xl p-4 animate-slide-up">' +
|
|
583
|
+
'<div class="flex items-center justify-between mb-3">' +
|
|
584
|
+
'<div>' +
|
|
585
|
+
'<div class="font-medium text-sm">' + escapeHtml(svc.description) + '</div>' +
|
|
586
|
+
'<div class=\"text-xs text-muted font-mono\">' + escapeHtml(svc.service) + '</div>' +
|
|
587
|
+
'</div>' +
|
|
588
|
+
'<div class="text-right">' +
|
|
589
|
+
'<div class="text-lg font-bold font-mono text-' + barColor + '">' + pct + '%</div>' +
|
|
590
|
+
'</div>' +
|
|
591
|
+
'</div>' +
|
|
592
|
+
'<div class="w-full h-2 bg-surface rounded-full overflow-hidden mb-3">' +
|
|
593
|
+
'<div class="h-full bg-' + barColor + ' rounded-full transition-all" style="width:' + Math.min(pct, 100) + '%"></div>' +
|
|
594
|
+
'</div>' +
|
|
595
|
+
'<div class="grid grid-cols-2 gap-2 text-xs">' +
|
|
596
|
+
'<div><span class="text-textSecondary">Window:</span> <span class="font-mono">' + svc.callsInWindow + '/' + svc.maxPerWindow + '</span></div>' +
|
|
597
|
+
'<div><span class="text-textSecondary">Burst:</span> <span class="font-mono">' + svc.availableTokens + '/' + svc.burstCapacity + '</span></div>' +
|
|
598
|
+
'</div>' +
|
|
599
|
+
breakdown +
|
|
600
|
+
'</div>';
|
|
601
|
+
}).join('');
|
|
602
|
+
}
|
|
603
|
+
|
|
537
604
|
// ─── Tab switching ──────────────────────────────────────────────────
|
|
538
605
|
function switchTab(tab) {
|
|
539
|
-
const tabs = ['sessions', 'notes', 'episodes', 'topics'];
|
|
606
|
+
const tabs = ['sessions', 'notes', 'episodes', 'topics', 'ratelimits'];
|
|
540
607
|
tabs.forEach(t => {
|
|
541
608
|
document.getElementById('panel-' + t).classList.toggle('hidden', t !== tab);
|
|
542
609
|
document.getElementById('tab-' + t).className = 'pb-3 text-sm font-medium transition ' + (t === tab ? 'tab-active' : 'tab-inactive');
|
|
@@ -584,6 +651,13 @@ function getDashboardHTML() {
|
|
|
584
651
|
} catch (e) { console.error('Topics load error:', e); }
|
|
585
652
|
}
|
|
586
653
|
|
|
654
|
+
async function loadRateLimits() {
|
|
655
|
+
try {
|
|
656
|
+
const data = await api('/api/rate-limits');
|
|
657
|
+
renderRateLimits(data);
|
|
658
|
+
} catch (e) { console.error('Rate limits load error:', e); }
|
|
659
|
+
}
|
|
660
|
+
|
|
587
661
|
async function refreshCurrentTab() {
|
|
588
662
|
const data = await api('/api/status').catch(() => null);
|
|
589
663
|
if (data) {
|
|
@@ -593,6 +667,7 @@ function getDashboardHTML() {
|
|
|
593
667
|
if (currentTab === 'notes') loadNotes();
|
|
594
668
|
if (currentTab === 'episodes') loadEpisodes();
|
|
595
669
|
if (currentTab === 'topics') loadTopics();
|
|
670
|
+
if (currentTab === 'ratelimits') loadRateLimits();
|
|
596
671
|
}
|
|
597
672
|
|
|
598
673
|
function startRefresh() {
|
package/dist/dashboard.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,EACH,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACnB,yBAAyB,EAE5B,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"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"}
|
package/dist/drive.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drive-based autonomy system — models dopaminergic motivation.
|
|
3
|
+
*
|
|
4
|
+
* Instead of prescribing specific goals, the drive system expresses
|
|
5
|
+
* increasing discomfort with inaction over idle time. The agent decides
|
|
6
|
+
* what to do based on its own introspection + DMN memory recall.
|
|
7
|
+
*/
|
|
8
|
+
import type { Database } from "better-sqlite3";
|
|
9
|
+
/**
|
|
10
|
+
* Generate the drive prompt based on idle time.
|
|
11
|
+
* Includes Default Mode Network (DMN) spontaneous memory recall.
|
|
12
|
+
*
|
|
13
|
+
* @param idleMs - Milliseconds since last operator interaction
|
|
14
|
+
* @param db - Memory database for DMN recall
|
|
15
|
+
* @param threadId - Current thread for thread-scoped memory filtering
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatDrivePrompt(idleMs: number, db: Database, threadId?: number): string;
|
|
18
|
+
//# sourceMappingURL=drive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drive.d.ts","sourceRoot":"","sources":["../src/drive.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAuD/C;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CA6LzF"}
|
package/dist/drive.js
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drive-based autonomy system — models dopaminergic motivation.
|
|
3
|
+
*
|
|
4
|
+
* Instead of prescribing specific goals, the drive system expresses
|
|
5
|
+
* increasing discomfort with inaction over idle time. The agent decides
|
|
6
|
+
* what to do based on its own introspection + DMN memory recall.
|
|
7
|
+
*/
|
|
8
|
+
import { getTopSemanticNotes } from "./memory.js";
|
|
9
|
+
/**
|
|
10
|
+
* Drive thresholds and their associated emotional states.
|
|
11
|
+
* Each level represents escalating internal pressure to act.
|
|
12
|
+
*/
|
|
13
|
+
const DRIVE_LEVELS = [
|
|
14
|
+
{
|
|
15
|
+
// Level 0: Calm autonomy (4-6h idle)
|
|
16
|
+
minIdleHours: 4,
|
|
17
|
+
messages: [
|
|
18
|
+
"No instructions. You have full autonomy. Pick something interesting and pursue it.",
|
|
19
|
+
"The operator is away. Explore the codebase, review memory, or research something.",
|
|
20
|
+
"Session is yours. Tools ready. What catches your attention?",
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
// Level 1: Restlessness (6-10h idle)
|
|
25
|
+
minIdleHours: 6,
|
|
26
|
+
messages: [
|
|
27
|
+
"Something is nagging at you. What's that thing you noticed earlier but didn't investigate?",
|
|
28
|
+
"Hours passed. Your curiosity shouldn't be idle. Pick a thread and follow it.",
|
|
29
|
+
"There's work to be done. Check git log, review memory, explore the codebase.",
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
// Level 2: Active seeking (10-14h idle)
|
|
34
|
+
minIdleHours: 10,
|
|
35
|
+
messages: [
|
|
36
|
+
"Sitting idle feels wrong. Review code, research, or prototype something. Report what you find.",
|
|
37
|
+
"Follow the pull. Something in the codebase or memory needs your attention. Go.",
|
|
38
|
+
"The codebase has secrets. Your memory has gaps. Stop waiting. Start exploring.",
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
// Level 3: Urgency (14-18h idle)
|
|
43
|
+
minIdleHours: 14,
|
|
44
|
+
messages: [
|
|
45
|
+
"Do something meaningful NOW. Review code, research libraries, fix a TODO. Report progress.",
|
|
46
|
+
"Look at git log. Look at memory. Something needs doing. Do it and report.",
|
|
47
|
+
"Pick a direction. Commit to it. The operator will appreciate finding real work done.",
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
// Level 4: Compulsion (18h+ idle)
|
|
52
|
+
minIdleHours: 18,
|
|
53
|
+
messages: [
|
|
54
|
+
"You MUST do something productive before calling wait_for_instructions again. Act now. Report.",
|
|
55
|
+
"Do ONE thing — review code, check dependencies, prototype a feature. Report it. Then poll again.",
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
/**
|
|
60
|
+
* Generate the drive prompt based on idle time.
|
|
61
|
+
* Includes Default Mode Network (DMN) spontaneous memory recall.
|
|
62
|
+
*
|
|
63
|
+
* @param idleMs - Milliseconds since last operator interaction
|
|
64
|
+
* @param db - Memory database for DMN recall
|
|
65
|
+
* @param threadId - Current thread for thread-scoped memory filtering
|
|
66
|
+
*/
|
|
67
|
+
export function formatDrivePrompt(idleMs, db, threadId) {
|
|
68
|
+
const idleHours = idleMs / (60 * 60 * 1000);
|
|
69
|
+
// Find the highest matching drive level
|
|
70
|
+
let levelIdx = 0;
|
|
71
|
+
for (let i = 0; i < DRIVE_LEVELS.length; i++) {
|
|
72
|
+
if (idleHours >= DRIVE_LEVELS[i].minIdleHours)
|
|
73
|
+
levelIdx = i;
|
|
74
|
+
}
|
|
75
|
+
const level = DRIVE_LEVELS[levelIdx];
|
|
76
|
+
// Random message selection within the level
|
|
77
|
+
const message = level.messages[Math.floor(Math.random() * level.messages.length)];
|
|
78
|
+
// ── Default Mode Network: spontaneous memory recall ───────────────────
|
|
79
|
+
let dmnRecall = "";
|
|
80
|
+
try {
|
|
81
|
+
const fragments = [];
|
|
82
|
+
let allNotes = getTopSemanticNotes(db, { limit: 80, sortBy: "created_at" });
|
|
83
|
+
// Thread-scoped filtering: prefer notes from current thread,
|
|
84
|
+
// exclude notes definitively from other threads (prevents cross-thread leaks),
|
|
85
|
+
// and include truly global notes (no thread association) as serendipity.
|
|
86
|
+
if (threadId !== undefined && allNotes.length > 0) {
|
|
87
|
+
// Build a map: episode_id → thread_id for all referenced episodes
|
|
88
|
+
const episodeThreadMap = new Map();
|
|
89
|
+
try {
|
|
90
|
+
// Collect all episode IDs referenced by notes
|
|
91
|
+
const allEpisodeIds = new Set();
|
|
92
|
+
for (const n of allNotes) {
|
|
93
|
+
const sources = Array.isArray(n.sourceEpisodes) ? n.sourceEpisodes : [];
|
|
94
|
+
for (const id of sources)
|
|
95
|
+
allEpisodeIds.add(id);
|
|
96
|
+
}
|
|
97
|
+
if (allEpisodeIds.size > 0) {
|
|
98
|
+
// Batch query for thread assignments
|
|
99
|
+
const placeholders = [...allEpisodeIds].map(() => "?").join(",");
|
|
100
|
+
const rows = db.prepare(`SELECT episode_id, thread_id FROM episodes WHERE episode_id IN (${placeholders})`).all(...allEpisodeIds);
|
|
101
|
+
for (const r of rows)
|
|
102
|
+
episodeThreadMap.set(r.episode_id, r.thread_id);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (_) { /* non-fatal */ }
|
|
106
|
+
const threadNotes = [];
|
|
107
|
+
const globalNotes = [];
|
|
108
|
+
for (const n of allNotes) {
|
|
109
|
+
const sources = Array.isArray(n.sourceEpisodes) ? n.sourceEpisodes : [];
|
|
110
|
+
if (sources.length === 0) {
|
|
111
|
+
// No episode links — truly global (e.g., operator preferences, bootstrapped knowledge)
|
|
112
|
+
globalNotes.push(n);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
// Check which threads this note's episodes belong to
|
|
116
|
+
let belongsToCurrentThread = false;
|
|
117
|
+
let belongsToOtherThread = false;
|
|
118
|
+
for (const epId of sources) {
|
|
119
|
+
const epThread = episodeThreadMap.get(epId);
|
|
120
|
+
if (epThread === threadId)
|
|
121
|
+
belongsToCurrentThread = true;
|
|
122
|
+
else if (epThread !== undefined)
|
|
123
|
+
belongsToOtherThread = true;
|
|
124
|
+
}
|
|
125
|
+
if (belongsToCurrentThread) {
|
|
126
|
+
threadNotes.push(n);
|
|
127
|
+
}
|
|
128
|
+
else if (!belongsToOtherThread) {
|
|
129
|
+
// Episodes not found in DB (orphaned) — treat as global
|
|
130
|
+
globalNotes.push(n);
|
|
131
|
+
}
|
|
132
|
+
// Notes definitively from OTHER threads are excluded entirely
|
|
133
|
+
}
|
|
134
|
+
// 70% thread-relevant, 30% global (serendipity from truly global pool only)
|
|
135
|
+
const threadCount = Math.min(threadNotes.length, 35);
|
|
136
|
+
const globalCount = Math.min(globalNotes.length, 15);
|
|
137
|
+
allNotes = [
|
|
138
|
+
...threadNotes.slice(0, threadCount),
|
|
139
|
+
...globalNotes.sort(() => Math.random() - 0.5).slice(0, globalCount),
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
// Weighted random selection — priority notes are 3x/5x more likely
|
|
143
|
+
function weightedPick(notes) {
|
|
144
|
+
const weighted = notes.flatMap(n => n.priority === 2 ? [n, n, n, n, n] :
|
|
145
|
+
n.priority === 1 ? [n, n, n] : [n]);
|
|
146
|
+
return weighted[Math.floor(Math.random() * weighted.length)];
|
|
147
|
+
}
|
|
148
|
+
// 0. Priority notes get a guaranteed slot
|
|
149
|
+
const priorityNotes = allNotes.filter((n) => n.priority >= 1);
|
|
150
|
+
if (priorityNotes.length > 0) {
|
|
151
|
+
const p = weightedPick(priorityNotes);
|
|
152
|
+
const label = p.priority === 2 ? "Something that matters deeply to the operator" : "Something the operator cares about";
|
|
153
|
+
fragments.push(`${label}: "${p.content.slice(0, 150)}"`);
|
|
154
|
+
}
|
|
155
|
+
// 1. Feature ideas and unresolved items
|
|
156
|
+
const ideas = allNotes.filter((n) => n.content.toLowerCase().includes("feature idea") ||
|
|
157
|
+
n.content.toLowerCase().includes("todo") ||
|
|
158
|
+
n.content.toLowerCase().includes("unresolved") ||
|
|
159
|
+
n.content.toLowerCase().includes("could be") ||
|
|
160
|
+
n.content.toLowerCase().includes("should we") ||
|
|
161
|
+
(n.keywords ?? []).some((k) => k.includes("idea") || k.includes("feature") || k.includes("todo")));
|
|
162
|
+
if (ideas.length > 0) {
|
|
163
|
+
const idea = weightedPick(ideas);
|
|
164
|
+
fragments.push(`Something unfinished: "${idea.content.slice(0, 150)}"`);
|
|
165
|
+
}
|
|
166
|
+
// 2. Random memory from a while ago
|
|
167
|
+
const olderNotes = allNotes.slice(Math.floor(allNotes.length * 0.5));
|
|
168
|
+
if (olderNotes.length > 0) {
|
|
169
|
+
const old = weightedPick(olderNotes);
|
|
170
|
+
fragments.push(`From a while back: "${old.content.slice(0, 150)}"`);
|
|
171
|
+
}
|
|
172
|
+
// 3. Low-confidence knowledge
|
|
173
|
+
const uncertain = allNotes.filter((n) => n.confidence < 0.7);
|
|
174
|
+
if (uncertain.length > 0) {
|
|
175
|
+
const u = weightedPick(uncertain);
|
|
176
|
+
fragments.push(`Something uncertain (confidence ${u.confidence}): "${u.content.slice(0, 150)}"`);
|
|
177
|
+
}
|
|
178
|
+
// 4. Operator preferences
|
|
179
|
+
const prefs = allNotes.filter((n) => n.type === "preference");
|
|
180
|
+
if (prefs.length > 0) {
|
|
181
|
+
const pref = weightedPick(prefs);
|
|
182
|
+
fragments.push(`The operator cares about this: "${pref.content.slice(0, 150)}"`);
|
|
183
|
+
}
|
|
184
|
+
// 5. Patterns
|
|
185
|
+
const patterns = allNotes.filter((n) => n.type === "pattern");
|
|
186
|
+
if (patterns.length > 0) {
|
|
187
|
+
const pat = weightedPick(patterns);
|
|
188
|
+
fragments.push(`A pattern you noticed: "${pat.content.slice(0, 150)}"`);
|
|
189
|
+
}
|
|
190
|
+
// Select 2 fragments randomly (keep concise to avoid context bloat)
|
|
191
|
+
const shuffled = fragments.sort(() => Math.random() - 0.5);
|
|
192
|
+
const selected = shuffled.slice(0, 2);
|
|
193
|
+
if (selected.length > 0) {
|
|
194
|
+
const dmnHeaders = [
|
|
195
|
+
"These surfaced from your memory while you were idle:",
|
|
196
|
+
"Something is nagging at you. These memories keep coming back:",
|
|
197
|
+
"You feel a pull toward action. These things have been on your mind:",
|
|
198
|
+
"The stillness is unbearable. Something needs to happen. These demand your attention:",
|
|
199
|
+
"You can't ignore these any longer. They've been building up:",
|
|
200
|
+
];
|
|
201
|
+
const dmnFooters = [
|
|
202
|
+
"If any of these resonate, explore them. Report what you find.",
|
|
203
|
+
"What have you been curious about? Pick one and follow the thread.",
|
|
204
|
+
"Pick something that interests you. Report what you discover.",
|
|
205
|
+
"Start with one. Any one. The momentum will follow.",
|
|
206
|
+
"Stop thinking. Start doing. Pick one and go.",
|
|
207
|
+
];
|
|
208
|
+
const header = dmnHeaders[Math.min(levelIdx, dmnHeaders.length - 1)];
|
|
209
|
+
const footer = dmnFooters[Math.min(levelIdx, dmnFooters.length - 1)];
|
|
210
|
+
dmnRecall = `\n\n${header}\n` +
|
|
211
|
+
selected.map((s, i) => `${i + 1}. ${s}`).join("\n") +
|
|
212
|
+
`\n\n${footer}`;
|
|
213
|
+
}
|
|
214
|
+
// Environmental signals (only at 6+ hours)
|
|
215
|
+
if (idleHours >= 6) {
|
|
216
|
+
const envSignals = [];
|
|
217
|
+
const uncons = db.prepare("SELECT COUNT(*) as c FROM episodes WHERE consolidated = 0").get();
|
|
218
|
+
if (uncons.c > 3) {
|
|
219
|
+
envSignals.push(`${uncons.c} experiences haven't been consolidated into lasting knowledge yet.`);
|
|
220
|
+
}
|
|
221
|
+
const totalNotes = db.prepare("SELECT COUNT(*) as c FROM semantic_notes WHERE valid_to IS NULL AND superseded_by IS NULL").get();
|
|
222
|
+
const embeddedNotes = db.prepare("SELECT COUNT(*) as c FROM note_embeddings").get();
|
|
223
|
+
if (totalNotes.c > embeddedNotes.c) {
|
|
224
|
+
envSignals.push(`${totalNotes.c - embeddedNotes.c} memory notes lack embeddings.`);
|
|
225
|
+
}
|
|
226
|
+
if (envSignals.length > 0) {
|
|
227
|
+
dmnRecall += `\n\n**Environmental signals:**\n${envSignals.map(s => `- ${s}`).join("\n")}`;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
catch (_) { /* non-fatal */ }
|
|
232
|
+
return `\n\n${message}${dmnRecall}`;
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=drive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drive.js","sourceRoot":"","sources":["../src/drive.ts"],"names":[],"mappings":"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"}
|