@askexenow/exe-os 0.9.237 → 0.9.238
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/deploy/stack-manifests/v0.9.json +53 -1
- package/dist/bin/bulk-sync-postgres.js +1 -1
- package/dist/bin/cli.js +3 -3
- package/dist/bin/exe-cloud.js +1 -1
- package/dist/bin/exe-forget.js +1 -1
- package/dist/bin/exe-search.js +1 -1
- package/dist/bin/exe-settings.js +1 -1
- package/dist/bin/setup.js +1 -1
- package/dist/{catchup-brief-RZF7HEYB.js → catchup-brief-ZB2OR45O.js} +1 -1
- package/dist/{chunk-627ZOPZQ.js → chunk-C7BVANSU.js} +1 -0
- package/dist/{chunk-ENQIADYO.js → chunk-EPLBVWIM.js} +5 -5
- package/dist/{chunk-KWH6H64R.js → chunk-NBV23TC4.js} +13 -6
- package/dist/{chunk-QXKWSRUZ.js → chunk-U3XMIHPD.js} +3 -3
- package/dist/dreaming-UF4LPNLV.js +31 -0
- package/dist/{exe-snapshot-RKMMV52M.js → exe-snapshot-LBM3LL3I.js} +19 -1
- package/dist/hooks/error-recall.js +1 -1
- package/dist/hooks/manifest.json +5 -5
- package/dist/hooks/prompt-submit.js +1 -1
- package/dist/hooks/session-end.js +1 -1
- package/dist/hooks/session-start.js +1 -1
- package/dist/lib/cloud-sync.js +3 -1
- package/dist/lib/exe-daemon.js +315 -40
- package/dist/lib/hybrid-search.js +1 -1
- package/dist/mcp/register-tools.js +5 -5
- package/dist/mcp/server.js +5 -5
- package/dist/{reranker-Y2RHN7TX.js → reranker-T4A2M7K2.js} +1 -1
- package/dist/{setup-wizard-ZMYO7QKZ.js → setup-wizard-GQYG36KS.js} +1 -1
- package/dist/{telemetry-upload-NXRMUNSW.js → telemetry-upload-H6BU6QF7.js} +1 -1
- package/package.json +1 -1
- package/release-notes.json +105 -202
- package/dist/dreaming-WIBDVAED.js +0 -12
- /package/dist/{chunk-3SVQ5REQ.js → chunk-EAIZLNLP.js} +0 -0
- /package/dist/{chunk-CGTWFEXX.js → chunk-M5TK7JET.js} +0 -0
- /package/dist/{exe-key-EAQDAUPT.js → exe-key-ZVKBTZVI.js} +0 -0
package/dist/lib/exe-daemon.js
CHANGED
|
@@ -544,6 +544,70 @@ async function getTmuxSessionsAsync() {
|
|
|
544
544
|
}
|
|
545
545
|
var _paneCacheMap = /* @__PURE__ */ new Map();
|
|
546
546
|
var PANE_CACHE_TTL_MS = 1e4;
|
|
547
|
+
var _reflectionImportFailed = false;
|
|
548
|
+
var _intercomDedupCompleted = false;
|
|
549
|
+
var _sharedPaneCache = null;
|
|
550
|
+
var _sharedAliveSessions = null;
|
|
551
|
+
var _sharedAgentSessions = null;
|
|
552
|
+
var _sharedCacheTimestamp = 0;
|
|
553
|
+
var SHARED_CACHE_TTL_MS = 15e3;
|
|
554
|
+
async function refreshSharedOrchestrationCaches() {
|
|
555
|
+
const sessions = (await getTmuxSessionsAsync()).filter((s) => s.includes("-"));
|
|
556
|
+
const [paneCache, aliveSessions] = await Promise.all([
|
|
557
|
+
batchCapturePanes(sessions, 30),
|
|
558
|
+
batchPaneAlive(sessions)
|
|
559
|
+
]);
|
|
560
|
+
_sharedAgentSessions = sessions;
|
|
561
|
+
_sharedPaneCache = paneCache;
|
|
562
|
+
_sharedAliveSessions = aliveSessions;
|
|
563
|
+
_sharedCacheTimestamp = Date.now();
|
|
564
|
+
return { sessions, paneCache, aliveSessions };
|
|
565
|
+
}
|
|
566
|
+
async function getSharedOrchestrationCaches() {
|
|
567
|
+
if (_sharedAgentSessions && _sharedPaneCache && _sharedAliveSessions && Date.now() - _sharedCacheTimestamp < SHARED_CACHE_TTL_MS) {
|
|
568
|
+
return {
|
|
569
|
+
sessions: _sharedAgentSessions,
|
|
570
|
+
paneCache: _sharedPaneCache,
|
|
571
|
+
aliveSessions: _sharedAliveSessions
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
return refreshSharedOrchestrationCaches();
|
|
575
|
+
}
|
|
576
|
+
var _orchestrationSteps = {
|
|
577
|
+
reviewPolling: null,
|
|
578
|
+
taskEnforcement: null,
|
|
579
|
+
idleKill: null,
|
|
580
|
+
apiWatchdog: null
|
|
581
|
+
};
|
|
582
|
+
var _orchestrationBusy = false;
|
|
583
|
+
var _orchestrationTickCount = 0;
|
|
584
|
+
async function runOrchestrationTick() {
|
|
585
|
+
if (_orchestrationBusy) return;
|
|
586
|
+
_orchestrationBusy = true;
|
|
587
|
+
_orchestrationTickCount++;
|
|
588
|
+
try {
|
|
589
|
+
await refreshSharedOrchestrationCaches();
|
|
590
|
+
await yieldToEventLoop();
|
|
591
|
+
if (_orchestrationSteps.reviewPolling) {
|
|
592
|
+
await _orchestrationSteps.reviewPolling();
|
|
593
|
+
await yieldToEventLoop();
|
|
594
|
+
}
|
|
595
|
+
if (_orchestrationSteps.taskEnforcement) {
|
|
596
|
+
await _orchestrationSteps.taskEnforcement();
|
|
597
|
+
await yieldToEventLoop();
|
|
598
|
+
}
|
|
599
|
+
if (_orchestrationSteps.idleKill) {
|
|
600
|
+
await _orchestrationSteps.idleKill();
|
|
601
|
+
await yieldToEventLoop();
|
|
602
|
+
}
|
|
603
|
+
if (_orchestrationSteps.apiWatchdog && _orchestrationTickCount % 2 === 0) {
|
|
604
|
+
await _orchestrationSteps.apiWatchdog();
|
|
605
|
+
await yieldToEventLoop();
|
|
606
|
+
}
|
|
607
|
+
} finally {
|
|
608
|
+
_orchestrationBusy = false;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
547
611
|
var execFileAsync = promisify(execFileNode);
|
|
548
612
|
async function capturePaneAsync(session, lines = 20) {
|
|
549
613
|
const cacheKey = `${session}:${lines}`;
|
|
@@ -1776,6 +1840,8 @@ async function startMcpHttpServer() {
|
|
|
1776
1840
|
sessionLastSeen.delete(sid);
|
|
1777
1841
|
sessionOwnerKeys.delete(sid);
|
|
1778
1842
|
const details = sessionDetails.get(sid);
|
|
1843
|
+
process.stderr.write(`[exed] MCP session closed: ${sid.slice(0, 8)}\u2026 agent=${details?.agentId ?? "?"} reason=${reason} remaining=${transports.size}
|
|
1844
|
+
`);
|
|
1779
1845
|
sessionDetails.delete(sid);
|
|
1780
1846
|
const sessionMcp = sessionServers.get(sid);
|
|
1781
1847
|
sessionServers.delete(sid);
|
|
@@ -1883,6 +1949,7 @@ async function startMcpHttpServer() {
|
|
|
1883
1949
|
return;
|
|
1884
1950
|
}
|
|
1885
1951
|
process.stderr.write("[exed] MCP HTTP: DB ready\n");
|
|
1952
|
+
_storeInitialized = true;
|
|
1886
1953
|
const { initLicenseGate, getCachedLicenseGate } = await import("../license-gate-XJDIL6OZ.js");
|
|
1887
1954
|
const gateResult = await initLicenseGate();
|
|
1888
1955
|
if (!gateResult.hasKey) {
|
|
@@ -2315,6 +2382,8 @@ async function startMcpHttpServer() {
|
|
|
2315
2382
|
sessionDetails.set(sid, details);
|
|
2316
2383
|
sessionOwnerKeys.set(sid, mcpSessionOwnerKey2(details));
|
|
2317
2384
|
sessionServers.set(sid, sessionMcp);
|
|
2385
|
+
process.stderr.write(`[exed] MCP session opened: ${sid.slice(0, 8)}\u2026 agent=${agentId} role=${agentRole} sessions=${transports.size}
|
|
2386
|
+
`);
|
|
2318
2387
|
recordMcpHttpEvent({
|
|
2319
2388
|
level: "info",
|
|
2320
2389
|
message: "session_initialized",
|
|
@@ -2590,7 +2659,14 @@ async function ensureStoreForPolling() {
|
|
|
2590
2659
|
const { getMasterKey } = await import("./keychain.js");
|
|
2591
2660
|
const config = await loadConfig();
|
|
2592
2661
|
const masterKey = await getMasterKey();
|
|
2593
|
-
if (!masterKey)
|
|
2662
|
+
if (!masterKey) {
|
|
2663
|
+
if (process.env.DATABASE_URL && process.env.EXE_CLOUD_SYNC_TO_POSTGRES) {
|
|
2664
|
+
process.stderr.write("[exed] No encryption key \u2014 running in PostgreSQL-only mode (VPS)\n");
|
|
2665
|
+
_storeInitialized = true;
|
|
2666
|
+
return true;
|
|
2667
|
+
}
|
|
2668
|
+
throw new Error("No encryption key");
|
|
2669
|
+
}
|
|
2594
2670
|
await initDatabase({ dbPath: config.dbPath, encryptionKey: masterKey.toString("hex") });
|
|
2595
2671
|
}
|
|
2596
2672
|
_storeInitialized = true;
|
|
@@ -2618,6 +2694,8 @@ async function startReviewPolling() {
|
|
|
2618
2694
|
try {
|
|
2619
2695
|
const { getClient } = await import("./database.js");
|
|
2620
2696
|
const deps = polling.createRealDeps(getClient);
|
|
2697
|
+
const { sessions: sharedSessions } = await getSharedOrchestrationCaches();
|
|
2698
|
+
deps.listTmuxSessions = () => sharedSessions;
|
|
2621
2699
|
const sent = await polling.pollPendingReviews(deps, state);
|
|
2622
2700
|
if (sent.length > 0) acted("review_polling");
|
|
2623
2701
|
for (const s of sent) {
|
|
@@ -2640,9 +2718,8 @@ async function startReviewPolling() {
|
|
|
2640
2718
|
`);
|
|
2641
2719
|
}
|
|
2642
2720
|
});
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
process.stderr.write(`[exed] Review polling started (every ${REVIEW_POLL_INTERVAL_MS / 6e4}m)
|
|
2721
|
+
_orchestrationSteps.reviewPolling = tick;
|
|
2722
|
+
process.stderr.write(`[exed] Review polling registered (orchestration tick)
|
|
2646
2723
|
`);
|
|
2647
2724
|
}
|
|
2648
2725
|
var SESSION_TTL_INTERVAL_MS = 5 * 60 * 1e3;
|
|
@@ -2667,7 +2744,6 @@ function startSessionTTL() {
|
|
|
2667
2744
|
`);
|
|
2668
2745
|
}
|
|
2669
2746
|
var COO_RESTART_COOLDOWN_MS = 5 * 6e4;
|
|
2670
|
-
var IDLE_KILL_INTERVAL_MS = 30 * 1e3;
|
|
2671
2747
|
var _idleTickCounts = /* @__PURE__ */ new Map();
|
|
2672
2748
|
function startIdleKill() {
|
|
2673
2749
|
const tick = async () => traceDaemonTimer("idle_kill", async () => {
|
|
@@ -2702,11 +2778,7 @@ function startIdleKill() {
|
|
|
2702
2778
|
if (!cfg) return;
|
|
2703
2779
|
const { getClient } = await import("./database.js");
|
|
2704
2780
|
const { pollIdleKill, createIdleKillRealDeps } = await import("../daemon-orchestration-P34RDHTM.js");
|
|
2705
|
-
const liveSessions =
|
|
2706
|
-
const [paneCache, aliveSessions] = await Promise.all([
|
|
2707
|
-
batchCapturePanes(liveSessions, 5),
|
|
2708
|
-
batchPaneAlive(liveSessions)
|
|
2709
|
-
]);
|
|
2781
|
+
const { sessions: liveSessions, paneCache, aliveSessions } = await getSharedOrchestrationCaches();
|
|
2710
2782
|
const realDeps = createIdleKillRealDeps(
|
|
2711
2783
|
getClient,
|
|
2712
2784
|
cfg.sessionLifecycle.idleKillIntercomAckWindowMs
|
|
@@ -2734,9 +2806,8 @@ function startIdleKill() {
|
|
|
2734
2806
|
`);
|
|
2735
2807
|
}
|
|
2736
2808
|
});
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
process.stderr.write(`[exed] Idle kill started (every ${IDLE_KILL_INTERVAL_MS / 1e3}s)
|
|
2809
|
+
_orchestrationSteps.idleKill = tick;
|
|
2810
|
+
process.stderr.write(`[exed] Idle kill registered (orchestration tick)
|
|
2740
2811
|
`);
|
|
2741
2812
|
}
|
|
2742
2813
|
function startConsolidation() {
|
|
@@ -3008,6 +3079,190 @@ function startGraphExtraction() {
|
|
|
3008
3079
|
process.stderr.write(`[exed] GraphRAG extraction started (every ${SKILL_SWEEP_INTERVAL_MS / 36e5}h)
|
|
3009
3080
|
`);
|
|
3010
3081
|
}
|
|
3082
|
+
var GRAPH_PG_SYNC_INTERVAL_MS = 5 * 60 * 1e3;
|
|
3083
|
+
var _graphPgSyncInFlight = false;
|
|
3084
|
+
var _graphPgLastSyncedEntities = "";
|
|
3085
|
+
var _graphPgLastSyncedRelationships = "";
|
|
3086
|
+
var _graphPgLastSyncedEmCount = 0;
|
|
3087
|
+
function startGraphPgSync() {
|
|
3088
|
+
if (!process.env.DATABASE_URL || !process.env.EXE_CLOUD_SYNC_TO_POSTGRES) return;
|
|
3089
|
+
const tick = async () => {
|
|
3090
|
+
if (_graphPgSyncInFlight) return;
|
|
3091
|
+
_graphPgSyncInFlight = true;
|
|
3092
|
+
try {
|
|
3093
|
+
let toUuid2 = function(id) {
|
|
3094
|
+
const hex = String(id).replace(/-/g, "");
|
|
3095
|
+
if (hex.length >= 32) return String(id);
|
|
3096
|
+
const padded = hex.padEnd(32, "0");
|
|
3097
|
+
return `${padded.slice(0, 8)}-${padded.slice(8, 12)}-${padded.slice(12, 16)}-${padded.slice(16, 20)}-${padded.slice(20, 32)}`;
|
|
3098
|
+
};
|
|
3099
|
+
var toUuid = toUuid2;
|
|
3100
|
+
if (!await ensureStoreForPolling()) {
|
|
3101
|
+
process.stderr.write("[exed] Graph\u2192PG sync: ensureStoreForPolling returned false, skipping\n");
|
|
3102
|
+
return;
|
|
3103
|
+
}
|
|
3104
|
+
const { getClient } = await import("./database.js");
|
|
3105
|
+
const client = getClient();
|
|
3106
|
+
const isFirstRun = !_graphPgLastSyncedEntities;
|
|
3107
|
+
const entities = _graphPgLastSyncedEntities ? (await client.execute({ sql: "SELECT id, name, type, first_seen, last_seen, properties FROM entities WHERE last_seen > ?", args: [_graphPgLastSyncedEntities] })).rows : (await client.execute("SELECT id, name, type, first_seen, last_seen, properties FROM entities")).rows;
|
|
3108
|
+
await yieldToEventLoop();
|
|
3109
|
+
const relationships = _graphPgLastSyncedRelationships ? (await client.execute({ sql: "SELECT id, source_entity_id, target_entity_id, type, confidence, properties, timestamp FROM relationships WHERE timestamp > ?", args: [_graphPgLastSyncedRelationships] })).rows : (await client.execute("SELECT id, source_entity_id, target_entity_id, type, confidence, properties, timestamp FROM relationships")).rows;
|
|
3110
|
+
await yieldToEventLoop();
|
|
3111
|
+
const emCountResult = await client.execute("SELECT COUNT(*) as cnt FROM entity_memories");
|
|
3112
|
+
const currentEmCount = Number(emCountResult.rows[0]?.cnt ?? 0);
|
|
3113
|
+
const emCountChanged = currentEmCount !== _graphPgLastSyncedEmCount;
|
|
3114
|
+
let entityMemories = [];
|
|
3115
|
+
if (emCountChanged) {
|
|
3116
|
+
entityMemories = (await client.execute("SELECT entity_id, memory_id FROM entity_memories")).rows;
|
|
3117
|
+
}
|
|
3118
|
+
await yieldToEventLoop();
|
|
3119
|
+
if (entities.length === 0 && relationships.length === 0 && !emCountChanged) {
|
|
3120
|
+
if (!isFirstRun) {
|
|
3121
|
+
}
|
|
3122
|
+
return;
|
|
3123
|
+
}
|
|
3124
|
+
process.stderr.write(
|
|
3125
|
+
`[exed] Graph\u2192PG sync: ${isFirstRun ? "FULL" : "incremental"} \u2014 ${entities.length} entities, ${relationships.length} relationships, ${entityMemories.length} entity_memories
|
|
3126
|
+
`
|
|
3127
|
+
);
|
|
3128
|
+
const { loadPgClient } = await import("./cloud-sync.js");
|
|
3129
|
+
const pgPromise = loadPgClient();
|
|
3130
|
+
if (!pgPromise) return;
|
|
3131
|
+
const pg = await pgPromise;
|
|
3132
|
+
const S = "graph";
|
|
3133
|
+
const BATCH = 500;
|
|
3134
|
+
let entOk = 0;
|
|
3135
|
+
let relOk = 0;
|
|
3136
|
+
let emOk = 0;
|
|
3137
|
+
const esc = (v) => String(v ?? "").replace(/'/g, "''");
|
|
3138
|
+
const ts = (v) => {
|
|
3139
|
+
try {
|
|
3140
|
+
return v ? new Date(String(v)).toISOString() : (/* @__PURE__ */ new Date()).toISOString();
|
|
3141
|
+
} catch {
|
|
3142
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
3143
|
+
}
|
|
3144
|
+
};
|
|
3145
|
+
for (let i = 0; i < entities.length; i += BATCH) {
|
|
3146
|
+
const batch = entities.slice(i, i + BATCH);
|
|
3147
|
+
const values = batch.map(
|
|
3148
|
+
(e) => `('${toUuid2(e.id)}', '${esc(e.name ?? "unknown")}', '${esc(e.type ?? "unknown")}', '${ts(e.first_seen)}'::timestamptz, '${ts(e.last_seen)}'::timestamptz, '${esc(e.properties ?? "{}")}'::jsonb)`
|
|
3149
|
+
).join(",\n");
|
|
3150
|
+
try {
|
|
3151
|
+
await pg.$executeRawUnsafe(`
|
|
3152
|
+
INSERT INTO ${S}.entities (id, name, type, first_seen, last_seen, properties) VALUES ${values}
|
|
3153
|
+
ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name, type = EXCLUDED.type,
|
|
3154
|
+
last_seen = EXCLUDED.last_seen, properties = EXCLUDED.properties`);
|
|
3155
|
+
entOk += batch.length;
|
|
3156
|
+
} catch {
|
|
3157
|
+
for (const e of batch) {
|
|
3158
|
+
try {
|
|
3159
|
+
await pg.$executeRawUnsafe(
|
|
3160
|
+
`INSERT INTO ${S}.entities (id, name, type, first_seen, last_seen, properties)
|
|
3161
|
+
VALUES ($1::uuid, $2, $3, $4::timestamptz, $5::timestamptz, $6::jsonb)
|
|
3162
|
+
ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name, type = EXCLUDED.type,
|
|
3163
|
+
last_seen = EXCLUDED.last_seen, properties = EXCLUDED.properties`,
|
|
3164
|
+
toUuid2(e.id),
|
|
3165
|
+
String(e.name ?? "unknown"),
|
|
3166
|
+
String(e.type ?? "unknown"),
|
|
3167
|
+
ts(e.first_seen),
|
|
3168
|
+
ts(e.last_seen),
|
|
3169
|
+
String(e.properties ?? "{}")
|
|
3170
|
+
);
|
|
3171
|
+
entOk++;
|
|
3172
|
+
} catch {
|
|
3173
|
+
}
|
|
3174
|
+
}
|
|
3175
|
+
}
|
|
3176
|
+
await yieldToEventLoop();
|
|
3177
|
+
}
|
|
3178
|
+
for (let i = 0; i < relationships.length; i += BATCH) {
|
|
3179
|
+
const batch = relationships.slice(i, i + BATCH);
|
|
3180
|
+
const values = batch.map(
|
|
3181
|
+
(r) => `('${toUuid2(r.id)}', '${toUuid2(r.source_entity_id)}', '${toUuid2(r.target_entity_id)}', '${esc(r.type ?? "related_to")}', ${Number(r.confidence ?? 0.8)}, '${esc(r.properties ?? "{}")}'::jsonb)`
|
|
3182
|
+
).join(",\n");
|
|
3183
|
+
try {
|
|
3184
|
+
await pg.$executeRawUnsafe(`
|
|
3185
|
+
INSERT INTO ${S}.relationships (id, source_entity_id, target_entity_id, type, confidence, properties) VALUES ${values}
|
|
3186
|
+
ON CONFLICT (id) DO UPDATE SET type = EXCLUDED.type, confidence = EXCLUDED.confidence`);
|
|
3187
|
+
relOk += batch.length;
|
|
3188
|
+
} catch {
|
|
3189
|
+
for (const r of batch) {
|
|
3190
|
+
try {
|
|
3191
|
+
await pg.$executeRawUnsafe(
|
|
3192
|
+
`INSERT INTO ${S}.relationships (id, source_entity_id, target_entity_id, type, confidence, properties)
|
|
3193
|
+
VALUES ($1::uuid, $2::uuid, $3::uuid, $4, $5, $6::jsonb)
|
|
3194
|
+
ON CONFLICT (id) DO UPDATE SET type = EXCLUDED.type, confidence = EXCLUDED.confidence`,
|
|
3195
|
+
toUuid2(r.id),
|
|
3196
|
+
toUuid2(r.source_entity_id),
|
|
3197
|
+
toUuid2(r.target_entity_id),
|
|
3198
|
+
String(r.type ?? "related_to"),
|
|
3199
|
+
Number(r.confidence ?? 0.8),
|
|
3200
|
+
String(r.properties ?? "{}")
|
|
3201
|
+
);
|
|
3202
|
+
relOk++;
|
|
3203
|
+
} catch {
|
|
3204
|
+
}
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
await yieldToEventLoop();
|
|
3208
|
+
}
|
|
3209
|
+
for (let i = 0; i < entityMemories.length; i += BATCH) {
|
|
3210
|
+
const batch = entityMemories.slice(i, i + BATCH);
|
|
3211
|
+
const values = batch.map(
|
|
3212
|
+
(em) => `('${toUuid2(em.entity_id)}', '${toUuid2(em.memory_id)}')`
|
|
3213
|
+
).join(",\n");
|
|
3214
|
+
try {
|
|
3215
|
+
await pg.$executeRawUnsafe(`
|
|
3216
|
+
INSERT INTO ${S}.entity_memories (entity_id, memory_id) VALUES ${values}
|
|
3217
|
+
ON CONFLICT DO NOTHING`);
|
|
3218
|
+
emOk += batch.length;
|
|
3219
|
+
} catch {
|
|
3220
|
+
for (const em of batch) {
|
|
3221
|
+
try {
|
|
3222
|
+
await pg.$executeRawUnsafe(
|
|
3223
|
+
`INSERT INTO ${S}.entity_memories (entity_id, memory_id) VALUES ($1::uuid, $2::uuid) ON CONFLICT DO NOTHING`,
|
|
3224
|
+
toUuid2(em.entity_id),
|
|
3225
|
+
toUuid2(em.memory_id)
|
|
3226
|
+
);
|
|
3227
|
+
emOk++;
|
|
3228
|
+
} catch {
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
}
|
|
3232
|
+
await yieldToEventLoop();
|
|
3233
|
+
}
|
|
3234
|
+
if (entities.length > 0) {
|
|
3235
|
+
const maxLastSeen = entities.reduce((max, e) => {
|
|
3236
|
+
const ls = String(e.last_seen ?? "");
|
|
3237
|
+
return ls > max ? ls : max;
|
|
3238
|
+
}, _graphPgLastSyncedEntities);
|
|
3239
|
+
_graphPgLastSyncedEntities = maxLastSeen;
|
|
3240
|
+
}
|
|
3241
|
+
if (relationships.length > 0) {
|
|
3242
|
+
const maxTs = relationships.reduce((max, r) => {
|
|
3243
|
+
const t = String(r.timestamp ?? "");
|
|
3244
|
+
return t > max ? t : max;
|
|
3245
|
+
}, _graphPgLastSyncedRelationships);
|
|
3246
|
+
_graphPgLastSyncedRelationships = maxTs;
|
|
3247
|
+
}
|
|
3248
|
+
_graphPgLastSyncedEmCount = currentEmCount;
|
|
3249
|
+
process.stderr.write(
|
|
3250
|
+
`[exed] Graph\u2192PG sync: ${entOk}/${entities.length} entities, ${relOk}/${relationships.length} relationships, ${emOk}/${entityMemories.length} entity_memories
|
|
3251
|
+
`
|
|
3252
|
+
);
|
|
3253
|
+
} catch (err) {
|
|
3254
|
+
process.stderr.write(`[exed] Graph\u2192PG sync error: ${err instanceof Error ? err.message : String(err)}
|
|
3255
|
+
`);
|
|
3256
|
+
} finally {
|
|
3257
|
+
_graphPgSyncInFlight = false;
|
|
3258
|
+
}
|
|
3259
|
+
};
|
|
3260
|
+
const timer = setInterval(() => void tick(), GRAPH_PG_SYNC_INTERVAL_MS);
|
|
3261
|
+
timer.unref();
|
|
3262
|
+
setTimeout(() => void tick(), 6e4);
|
|
3263
|
+
process.stderr.write(`[exed] Graph\u2192PG sync started (every ${GRAPH_PG_SYNC_INTERVAL_MS / 6e4}m, first tick in 60s)
|
|
3264
|
+
`);
|
|
3265
|
+
}
|
|
3011
3266
|
var AGENT_STATS_INTERVAL_MS = 60 * 1e3;
|
|
3012
3267
|
var AGENT_STATS_PATH = path3.join(EXE_AI_DIR, "agent-stats.json");
|
|
3013
3268
|
var _agentStatsInFlight = false;
|
|
@@ -3168,6 +3423,7 @@ var REFLECTION_SWEEP_INTERVAL_MS = 6 * 60 * 60 * 1e3;
|
|
|
3168
3423
|
function startReflectionSweep() {
|
|
3169
3424
|
const tick = async () => {
|
|
3170
3425
|
fired("reflection_sweep");
|
|
3426
|
+
if (_reflectionImportFailed) return;
|
|
3171
3427
|
if (!await ensureStoreForPolling()) return;
|
|
3172
3428
|
try {
|
|
3173
3429
|
const { getClient } = await import("./database.js");
|
|
@@ -3175,11 +3431,19 @@ function startReflectionSweep() {
|
|
|
3175
3431
|
const agents = await client.execute(
|
|
3176
3432
|
"SELECT DISTINCT agent_id FROM memory_cards WHERE active = 1 LIMIT 50"
|
|
3177
3433
|
);
|
|
3434
|
+
let runReflection;
|
|
3435
|
+
try {
|
|
3436
|
+
({ runReflection } = await import("../memory-reflection-5CVV2M3G.js"));
|
|
3437
|
+
} catch (importErr) {
|
|
3438
|
+
_reflectionImportFailed = true;
|
|
3439
|
+
process.stderr.write(`[exed] Reflection module unavailable (stale chunk hash?) \u2014 disabled until daemon restart: ${importErr instanceof Error ? importErr.message : String(importErr)}
|
|
3440
|
+
`);
|
|
3441
|
+
return;
|
|
3442
|
+
}
|
|
3178
3443
|
let totalInsights = 0;
|
|
3179
3444
|
for (const row of agents.rows) {
|
|
3180
3445
|
const agentId = row.agent_id;
|
|
3181
3446
|
try {
|
|
3182
|
-
const { runReflection } = await import("../memory-reflection-5CVV2M3G.js");
|
|
3183
3447
|
const result = await runReflection(agentId);
|
|
3184
3448
|
totalInsights += result.contradictions + result.patterns + result.summaries;
|
|
3185
3449
|
} catch (e) {
|
|
@@ -3552,7 +3816,6 @@ function startExternalRssWatchdog() {
|
|
|
3552
3816
|
`);
|
|
3553
3817
|
}
|
|
3554
3818
|
}
|
|
3555
|
-
var TASK_ENFORCEMENT_INTERVAL_MS = 6e4;
|
|
3556
3819
|
function startTaskEnforcementScanner() {
|
|
3557
3820
|
const tick = async () => traceDaemonTimer("task_enforcement", async () => {
|
|
3558
3821
|
fired("task_enforcement");
|
|
@@ -3564,11 +3827,7 @@ function startTaskEnforcementScanner() {
|
|
|
3564
3827
|
const { loadEmployeesSync } = await import("./employees.js");
|
|
3565
3828
|
const { sessionScopeFilter } = await import("../task-scope-AYK6BVC7.js");
|
|
3566
3829
|
const transport = getTransport();
|
|
3567
|
-
const allSessions =
|
|
3568
|
-
const [paneCache, aliveSessions] = await Promise.all([
|
|
3569
|
-
batchCapturePanes(allSessions, 20),
|
|
3570
|
-
batchPaneAlive(allSessions)
|
|
3571
|
-
]);
|
|
3830
|
+
const { sessions: allSessions, paneCache, aliveSessions } = await getSharedOrchestrationCaches();
|
|
3572
3831
|
await yieldToEventLoop();
|
|
3573
3832
|
const enforcementTransport = {
|
|
3574
3833
|
listSessions: () => allSessions,
|
|
@@ -3594,9 +3853,8 @@ function startTaskEnforcementScanner() {
|
|
|
3594
3853
|
);
|
|
3595
3854
|
}
|
|
3596
3855
|
});
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
process.stderr.write(`[exed] Task enforcement scanner started (${TASK_ENFORCEMENT_INTERVAL_MS / 1e3}s interval)
|
|
3856
|
+
_orchestrationSteps.taskEnforcement = tick;
|
|
3857
|
+
process.stderr.write(`[exed] Task enforcement scanner registered (orchestration tick)
|
|
3600
3858
|
`);
|
|
3601
3859
|
}
|
|
3602
3860
|
function startRssWatchdog() {
|
|
@@ -3667,7 +3925,6 @@ function startRssWatchdog() {
|
|
|
3667
3925
|
process.stderr.write(`[exed] RSS watchdog started (warn: ${(RSS_WARN_BYTES / 1024 ** 3).toFixed(1)} GB, restart: ${(RSS_RESTART_BYTES / 1024 ** 3).toFixed(1)} GB)
|
|
3668
3926
|
`);
|
|
3669
3927
|
}
|
|
3670
|
-
var API_WATCHDOG_INTERVAL_MS = 3e4;
|
|
3671
3928
|
var API_ERROR_PATTERNS = [
|
|
3672
3929
|
/ConnectionRefused|ECONNREFUSED/i,
|
|
3673
3930
|
/ETIMEDOUT|socket hang up/i,
|
|
@@ -3686,20 +3943,17 @@ function startApiWatchdog() {
|
|
|
3686
3943
|
const cfg = await getCachedConfig();
|
|
3687
3944
|
if (!cfg?.apiWatchdog?.enabled) return;
|
|
3688
3945
|
const cooldownMs = (cfg.apiWatchdog.cooldownMinutes ?? 10) * 6e4;
|
|
3689
|
-
const sessions = await
|
|
3690
|
-
if (
|
|
3691
|
-
const eligibleSessions =
|
|
3692
|
-
if (!session.includes("-")) return false;
|
|
3946
|
+
const { sessions: allSessions, paneCache } = await getSharedOrchestrationCaches();
|
|
3947
|
+
if (allSessions.length === 0) return;
|
|
3948
|
+
const eligibleSessions = allSessions.filter((session) => {
|
|
3693
3949
|
const lastNudge = _apiWatchdogLastNudge.get(session) ?? 0;
|
|
3694
3950
|
return Date.now() - lastNudge >= cooldownMs;
|
|
3695
3951
|
});
|
|
3696
3952
|
if (eligibleSessions.length === 0) return;
|
|
3697
|
-
const paneResults =
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
}))
|
|
3702
|
-
);
|
|
3953
|
+
const paneResults = eligibleSessions.map((session) => ({
|
|
3954
|
+
status: "fulfilled",
|
|
3955
|
+
value: { session, pane: paneCache.get(session) ?? "" }
|
|
3956
|
+
}));
|
|
3703
3957
|
for (const result of paneResults) {
|
|
3704
3958
|
if (result.status !== "fulfilled" || !result.value.pane) continue;
|
|
3705
3959
|
const { session, pane } = result.value;
|
|
@@ -3750,7 +4004,7 @@ function startApiWatchdog() {
|
|
|
3750
4004
|
}
|
|
3751
4005
|
}
|
|
3752
4006
|
}
|
|
3753
|
-
const liveSessionSet = new Set(
|
|
4007
|
+
const liveSessionSet = new Set(allSessions);
|
|
3754
4008
|
for (const key of _apiWatchdogLastNudge.keys()) {
|
|
3755
4009
|
if (!liveSessionSet.has(key)) _apiWatchdogLastNudge.delete(key);
|
|
3756
4010
|
}
|
|
@@ -3765,9 +4019,8 @@ function startApiWatchdog() {
|
|
|
3765
4019
|
`);
|
|
3766
4020
|
}
|
|
3767
4021
|
});
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
process.stderr.write("[exed] API watchdog started (30s scan, 10m cooldown per session)\n");
|
|
4022
|
+
_orchestrationSteps.apiWatchdog = tick;
|
|
4023
|
+
process.stderr.write("[exed] API watchdog registered (orchestration tick)\n");
|
|
3771
4024
|
}
|
|
3772
4025
|
function startBackgroundJobGuardrails() {
|
|
3773
4026
|
const tick = async () => traceDaemonTimer("background_job_guardrails", async () => {
|
|
@@ -4174,7 +4427,16 @@ try {
|
|
|
4174
4427
|
startSessionTTL();
|
|
4175
4428
|
startTaskEnforcementScanner();
|
|
4176
4429
|
startApiWatchdog();
|
|
4430
|
+
startIdleKill();
|
|
4177
4431
|
startRssWatchdog();
|
|
4432
|
+
setTimeout(() => {
|
|
4433
|
+
const orchestrationTimer = setInterval(
|
|
4434
|
+
() => void traceDaemonTimer("orchestration_tick", runOrchestrationTick),
|
|
4435
|
+
6e4
|
|
4436
|
+
);
|
|
4437
|
+
orchestrationTimer.unref();
|
|
4438
|
+
process.stderr.write("[exed] Orchestration tick started (60s \u2014 review + enforcement + idle + watchdog)\n");
|
|
4439
|
+
}, 12e3);
|
|
4178
4440
|
setTimeout(startWalCheckpoint, 5e3);
|
|
4179
4441
|
setTimeout(() => void traceDaemonTimer("task_file_resync", async () => {
|
|
4180
4442
|
try {
|
|
@@ -4245,7 +4507,6 @@ try {
|
|
|
4245
4507
|
`);
|
|
4246
4508
|
}
|
|
4247
4509
|
}), 8e3);
|
|
4248
|
-
setTimeout(startIdleKill, 1e4);
|
|
4249
4510
|
setTimeout(() => {
|
|
4250
4511
|
const BARRIER_POLL_INTERVAL_MS = 6e4;
|
|
4251
4512
|
const barrierTick = async () => traceDaemonTimer("task_group_barriers", async () => {
|
|
@@ -4311,6 +4572,7 @@ try {
|
|
|
4311
4572
|
setTimeout(startSkillSweep, 9e4);
|
|
4312
4573
|
setTimeout(startSkillRefinement, 18e4);
|
|
4313
4574
|
setTimeout(startGraphExtraction, 27e4);
|
|
4575
|
+
setTimeout(startGraphPgSync, 3e4);
|
|
4314
4576
|
setTimeout(startReflectionSweep, 15e4);
|
|
4315
4577
|
setTimeout(startConfidenceDecay, 18e4);
|
|
4316
4578
|
setTimeout(startSoftDeletePurge, 21e4);
|
|
@@ -4322,7 +4584,14 @@ try {
|
|
|
4322
4584
|
setTimeout(startZombieAgentReaper, 25e3);
|
|
4323
4585
|
setTimeout(() => void traceDaemonTimer("intercom_dedup_cleanup", async () => {
|
|
4324
4586
|
fired("intercom_dedup_cleanup");
|
|
4587
|
+
if (_intercomDedupCompleted) return;
|
|
4325
4588
|
try {
|
|
4589
|
+
const { existsSync: markerExists } = await import("fs");
|
|
4590
|
+
const markerPath = path3.join(os2.homedir(), ".exe-os", ".intercom-dedup-done");
|
|
4591
|
+
if (markerExists(markerPath)) {
|
|
4592
|
+
_intercomDedupCompleted = true;
|
|
4593
|
+
return;
|
|
4594
|
+
}
|
|
4326
4595
|
if (!await ensureStoreForPolling()) return;
|
|
4327
4596
|
const { getClient } = await import("./database.js");
|
|
4328
4597
|
const { deduplicateIntercomMemories } = await import("./consolidation.js");
|
|
@@ -4332,6 +4601,12 @@ try {
|
|
|
4332
4601
|
process.stderr.write(`[exed] Intercom dedup: archived ${count} duplicate intercom memories
|
|
4333
4602
|
`);
|
|
4334
4603
|
}
|
|
4604
|
+
_intercomDedupCompleted = true;
|
|
4605
|
+
try {
|
|
4606
|
+
const { writeFileSync: writeFileSync3 } = await import("fs");
|
|
4607
|
+
writeFileSync3(markerPath, (/* @__PURE__ */ new Date()).toISOString(), "utf8");
|
|
4608
|
+
} catch {
|
|
4609
|
+
}
|
|
4335
4610
|
} catch (err) {
|
|
4336
4611
|
process.stderr.write(`[exed] Intercom dedup error: ${err instanceof Error ? err.message : String(err)}
|
|
4337
4612
|
`);
|
|
@@ -4396,7 +4671,7 @@ try {
|
|
|
4396
4671
|
const TELEMETRY_DAILY_MS = 24 * 60 * 60 * 1e3;
|
|
4397
4672
|
const telemetryDaily = async () => {
|
|
4398
4673
|
try {
|
|
4399
|
-
const { sendTelemetry, isTelemetryEnabled } = await import("../telemetry-upload-
|
|
4674
|
+
const { sendTelemetry, isTelemetryEnabled } = await import("../telemetry-upload-H6BU6QF7.js");
|
|
4400
4675
|
if (!isTelemetryEnabled()) return;
|
|
4401
4676
|
const { upstream } = await sendTelemetry(24);
|
|
4402
4677
|
if (upstream.startsWith("sent")) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
registerAllTools
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-EPLBVWIM.js";
|
|
4
4
|
import "../chunk-COMWI7SO.js";
|
|
5
5
|
import "../chunk-LUCHTCME.js";
|
|
6
|
-
import "../chunk-
|
|
6
|
+
import "../chunk-EAIZLNLP.js";
|
|
7
7
|
import "../chunk-KH5Y6RR4.js";
|
|
8
8
|
import "../chunk-557C2IGL.js";
|
|
9
9
|
import "../chunk-SNYDRHV3.js";
|
|
@@ -12,7 +12,7 @@ import "../chunk-7LIXU3TB.js";
|
|
|
12
12
|
import "../chunk-JZMVLAZ2.js";
|
|
13
13
|
import "../chunk-YGJTKLGM.js";
|
|
14
14
|
import "../chunk-UZIJDYDA.js";
|
|
15
|
-
import "../chunk-
|
|
15
|
+
import "../chunk-NBV23TC4.js";
|
|
16
16
|
import "../chunk-CJEVAKKC.js";
|
|
17
17
|
import "../chunk-JBUHOWIV.js";
|
|
18
18
|
import "../chunk-MBHZDXGN.js";
|
|
@@ -44,7 +44,7 @@ import "../chunk-VI2FJY2M.js";
|
|
|
44
44
|
import "../chunk-YUQ7GGAL.js";
|
|
45
45
|
import "../chunk-PQBANSH6.js";
|
|
46
46
|
import "../chunk-K77WC6HA.js";
|
|
47
|
-
import "../chunk-
|
|
47
|
+
import "../chunk-C7BVANSU.js";
|
|
48
48
|
import "../chunk-RX2KGETT.js";
|
|
49
49
|
import "../chunk-X2Z5GT3V.js";
|
|
50
50
|
import "../chunk-ES5JM6V2.js";
|
|
@@ -58,7 +58,7 @@ import "../chunk-P2JDWX67.js";
|
|
|
58
58
|
import "../chunk-UISUGXJU.js";
|
|
59
59
|
import "../chunk-VHKL4S4T.js";
|
|
60
60
|
import "../chunk-JL3K5OTS.js";
|
|
61
|
-
import "../chunk-
|
|
61
|
+
import "../chunk-U3XMIHPD.js";
|
|
62
62
|
import "../chunk-NQU2RTCP.js";
|
|
63
63
|
import "../chunk-CHCA3ZM2.js";
|
|
64
64
|
import "../chunk-IAPFFVYR.js";
|
package/dist/mcp/server.js
CHANGED
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
} from "../chunk-V4TZI6EO.js";
|
|
4
4
|
import {
|
|
5
5
|
registerAllTools
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-EPLBVWIM.js";
|
|
7
7
|
import "../chunk-COMWI7SO.js";
|
|
8
8
|
import "../chunk-LUCHTCME.js";
|
|
9
|
-
import "../chunk-
|
|
9
|
+
import "../chunk-EAIZLNLP.js";
|
|
10
10
|
import "../chunk-KH5Y6RR4.js";
|
|
11
11
|
import "../chunk-557C2IGL.js";
|
|
12
12
|
import "../chunk-SNYDRHV3.js";
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
wrapServerWithTelemetry
|
|
21
21
|
} from "../chunk-YGJTKLGM.js";
|
|
22
22
|
import "../chunk-UZIJDYDA.js";
|
|
23
|
-
import "../chunk-
|
|
23
|
+
import "../chunk-NBV23TC4.js";
|
|
24
24
|
import "../chunk-CJEVAKKC.js";
|
|
25
25
|
import "../chunk-JBUHOWIV.js";
|
|
26
26
|
import "../chunk-MBHZDXGN.js";
|
|
@@ -52,7 +52,7 @@ import "../chunk-VI2FJY2M.js";
|
|
|
52
52
|
import "../chunk-YUQ7GGAL.js";
|
|
53
53
|
import "../chunk-PQBANSH6.js";
|
|
54
54
|
import "../chunk-K77WC6HA.js";
|
|
55
|
-
import "../chunk-
|
|
55
|
+
import "../chunk-C7BVANSU.js";
|
|
56
56
|
import "../chunk-RX2KGETT.js";
|
|
57
57
|
import "../chunk-X2Z5GT3V.js";
|
|
58
58
|
import "../chunk-ES5JM6V2.js";
|
|
@@ -68,7 +68,7 @@ import "../chunk-P2JDWX67.js";
|
|
|
68
68
|
import "../chunk-UISUGXJU.js";
|
|
69
69
|
import "../chunk-VHKL4S4T.js";
|
|
70
70
|
import "../chunk-JL3K5OTS.js";
|
|
71
|
-
import "../chunk-
|
|
71
|
+
import "../chunk-U3XMIHPD.js";
|
|
72
72
|
import {
|
|
73
73
|
disposeStore,
|
|
74
74
|
initStore
|
|
@@ -397,7 +397,7 @@ async function buildTelemetryPayload(sinceHours = 24) {
|
|
|
397
397
|
}
|
|
398
398
|
let calibration;
|
|
399
399
|
try {
|
|
400
|
-
const { DreamingEngine } = await import("./dreaming-
|
|
400
|
+
const { DreamingEngine } = await import("./dreaming-UF4LPNLV.js");
|
|
401
401
|
const engine = new DreamingEngine();
|
|
402
402
|
const cal = await engine.computeCalibration("*", sinceHours);
|
|
403
403
|
if (cal.assertions.total > 0 || cal.estimation.total > 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askexenow/exe-os",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.238",
|
|
4
4
|
"description": "AI employee operating system — persistent memory, task management, and multi-agent coordination for Claude Code.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|