gnosys 5.11.4 → 5.12.2
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/cli.js +377 -5162
- package/dist/index.js +542 -244
- package/dist/lib/addCommand.d.ts +9 -0
- package/dist/lib/addCommand.js +102 -0
- package/dist/lib/addStructuredCommand.d.ts +16 -0
- package/dist/lib/addStructuredCommand.js +103 -0
- package/dist/lib/ambiguityCommand.d.ts +4 -0
- package/dist/lib/ambiguityCommand.js +36 -0
- package/dist/lib/apiKeyVault.d.ts +78 -0
- package/dist/lib/apiKeyVault.js +447 -0
- package/dist/lib/archive.js +0 -2
- package/dist/lib/askCommand.d.ts +13 -0
- package/dist/lib/askCommand.js +145 -0
- package/dist/lib/attachCommand.d.ts +17 -0
- package/dist/lib/attachCommand.js +66 -0
- package/dist/lib/attachments.d.ts +43 -2
- package/dist/lib/attachments.js +81 -2
- package/dist/lib/audioExtract.js +4 -1
- package/dist/lib/auditCommand.d.ts +7 -0
- package/dist/lib/auditCommand.js +27 -0
- package/dist/lib/backupCommand.d.ts +6 -0
- package/dist/lib/backupCommand.js +54 -0
- package/dist/lib/bootstrapCommand.d.ts +15 -0
- package/dist/lib/bootstrapCommand.js +51 -0
- package/dist/lib/briefingCommand.d.ts +7 -0
- package/dist/lib/briefingCommand.js +92 -0
- package/dist/lib/centralizeCommand.d.ts +5 -0
- package/dist/lib/centralizeCommand.js +16 -0
- package/dist/lib/chat/choose.js +2 -2
- package/dist/lib/chatCommand.d.ts +12 -0
- package/dist/lib/chatCommand.js +46 -0
- package/dist/lib/checkCommand.d.ts +4 -0
- package/dist/lib/checkCommand.js +133 -0
- package/dist/lib/clientReadOverlay.d.ts +27 -0
- package/dist/lib/clientReadOverlay.js +76 -0
- package/dist/lib/clientReadResolve.d.ts +32 -0
- package/dist/lib/clientReadResolve.js +84 -0
- package/dist/lib/commitContextCommand.d.ts +9 -0
- package/dist/lib/commitContextCommand.js +142 -0
- package/dist/lib/config.d.ts +41 -48
- package/dist/lib/config.js +58 -57
- package/dist/lib/configCommand.d.ts +10 -0
- package/dist/lib/configCommand.js +321 -0
- package/dist/lib/connectCommand.d.ts +8 -0
- package/dist/lib/connectCommand.js +19 -0
- package/dist/lib/db.d.ts +68 -1
- package/dist/lib/db.js +385 -120
- package/dist/lib/dbWrite.d.ts +1 -1
- package/dist/lib/dearchiveCommand.d.ts +7 -0
- package/dist/lib/dearchiveCommand.js +41 -0
- package/dist/lib/discoverCommand.d.ts +9 -0
- package/dist/lib/discoverCommand.js +87 -0
- package/dist/lib/doctorCommand.d.ts +6 -0
- package/dist/lib/doctorCommand.js +256 -0
- package/dist/lib/docxExtract.js +1 -1
- package/dist/lib/dream.d.ts +50 -2
- package/dist/lib/dream.js +324 -30
- package/dist/lib/dreamCommand.d.ts +10 -0
- package/dist/lib/dreamCommand.js +195 -0
- package/dist/lib/dreamLaunchd.d.ts +2 -0
- package/dist/lib/dreamLaunchd.js +72 -0
- package/dist/lib/dreamLogCommand.d.ts +10 -0
- package/dist/lib/dreamLogCommand.js +58 -0
- package/dist/lib/dreamReport.d.ts +7 -0
- package/dist/lib/dreamReport.js +114 -0
- package/dist/lib/dreamRunLog.d.ts +121 -0
- package/dist/lib/dreamRunLog.js +234 -0
- package/dist/lib/embeddings.js +3 -3
- package/dist/lib/exportCommand.d.ts +18 -0
- package/dist/lib/exportCommand.js +101 -0
- package/dist/lib/exportProject.d.ts +3 -2
- package/dist/lib/exportProject.js +2 -1
- package/dist/lib/federated.js +1 -1
- package/dist/lib/fsearchCommand.d.ts +8 -0
- package/dist/lib/fsearchCommand.js +44 -0
- package/dist/lib/graphCommand.d.ts +4 -0
- package/dist/lib/graphCommand.js +68 -0
- package/dist/lib/helperGenerateCommand.d.ts +5 -0
- package/dist/lib/helperGenerateCommand.js +27 -0
- package/dist/lib/historyCommand.d.ts +5 -0
- package/dist/lib/historyCommand.js +51 -0
- package/dist/lib/hybridSearchCommand.d.ts +12 -0
- package/dist/lib/hybridSearchCommand.js +95 -0
- package/dist/lib/importCommand.d.ts +16 -0
- package/dist/lib/importCommand.js +89 -0
- package/dist/lib/importProject.js +2 -1
- package/dist/lib/importProjectCommand.d.ts +6 -0
- package/dist/lib/importProjectCommand.js +43 -0
- package/dist/lib/ingestCommand.d.ts +13 -0
- package/dist/lib/ingestCommand.js +95 -0
- package/dist/lib/installOutput.d.ts +36 -0
- package/dist/lib/installOutput.js +55 -0
- package/dist/lib/lensCommand.d.ts +20 -0
- package/dist/lib/lensCommand.js +61 -0
- package/dist/lib/lensing.d.ts +1 -0
- package/dist/lib/lensing.js +50 -9
- package/dist/lib/linksCommand.d.ts +7 -0
- package/dist/lib/linksCommand.js +48 -0
- package/dist/lib/listCommand.d.ts +8 -0
- package/dist/lib/listCommand.js +74 -0
- package/dist/lib/llm.d.ts +1 -1
- package/dist/lib/llm.js +27 -9
- package/dist/lib/localDiskCheck.d.ts +17 -0
- package/dist/lib/localDiskCheck.js +54 -0
- package/dist/lib/lock.d.ts +1 -1
- package/dist/lib/lock.js +5 -3
- package/dist/lib/machineConfig.d.ts +11 -1
- package/dist/lib/machineConfig.js +16 -0
- package/dist/lib/machineRegistry.d.ts +61 -0
- package/dist/lib/machineRegistry.js +80 -0
- package/dist/lib/maintainCommand.d.ts +8 -0
- package/dist/lib/maintainCommand.js +34 -0
- package/dist/lib/masterLease.d.ts +20 -0
- package/dist/lib/masterLease.js +68 -0
- package/dist/lib/migrate.js +0 -1
- package/dist/lib/migrateCommand.d.ts +7 -0
- package/dist/lib/migrateCommand.js +158 -0
- package/dist/lib/migrateDbCommand.d.ts +9 -0
- package/dist/lib/migrateDbCommand.js +94 -0
- package/dist/lib/modelValidation.d.ts +5 -0
- package/dist/lib/modelValidation.js +27 -0
- package/dist/lib/multimodalIngest.js +1 -1
- package/dist/lib/openrouterTiers.d.ts +29 -0
- package/dist/lib/openrouterTiers.js +113 -0
- package/dist/lib/platform.d.ts +0 -6
- package/dist/lib/platform.js +0 -28
- package/dist/lib/prefCommand.d.ts +10 -0
- package/dist/lib/prefCommand.js +118 -0
- package/dist/lib/projectsCommand.d.ts +8 -0
- package/dist/lib/projectsCommand.js +131 -0
- package/dist/lib/readCommand.d.ts +7 -0
- package/dist/lib/readCommand.js +63 -0
- package/dist/lib/recall.d.ts +3 -0
- package/dist/lib/recall.js +19 -4
- package/dist/lib/recallCommand.d.ts +11 -0
- package/dist/lib/recallCommand.js +112 -0
- package/dist/lib/reflectCommand.d.ts +8 -0
- package/dist/lib/reflectCommand.js +61 -0
- package/dist/lib/reindexCommand.d.ts +4 -0
- package/dist/lib/reindexCommand.js +34 -0
- package/dist/lib/reindexGraphCommand.d.ts +4 -0
- package/dist/lib/reindexGraphCommand.js +12 -0
- package/dist/lib/reinforceCommand.d.ts +8 -0
- package/dist/lib/reinforceCommand.js +40 -0
- package/dist/lib/remote.d.ts +5 -1
- package/dist/lib/remote.js +5 -1
- package/dist/lib/remoteWizard.d.ts +24 -5
- package/dist/lib/remoteWizard.js +308 -319
- package/dist/lib/restoreCommand.d.ts +5 -0
- package/dist/lib/restoreCommand.js +35 -0
- package/dist/lib/rulesGen.d.ts +8 -0
- package/dist/lib/rulesGen.js +16 -0
- package/dist/lib/sandboxStartCommand.d.ts +6 -0
- package/dist/lib/sandboxStartCommand.js +25 -0
- package/dist/lib/sandboxStatusCommand.d.ts +4 -0
- package/dist/lib/sandboxStatusCommand.js +24 -0
- package/dist/lib/sandboxStopCommand.d.ts +4 -0
- package/dist/lib/sandboxStopCommand.js +21 -0
- package/dist/lib/search.d.ts +0 -2
- package/dist/lib/search.js +0 -7
- package/dist/lib/searchCommand.d.ts +9 -0
- package/dist/lib/searchCommand.js +90 -0
- package/dist/lib/semanticSearchCommand.d.ts +8 -0
- package/dist/lib/semanticSearchCommand.js +52 -0
- package/dist/lib/setup/configSetRender.js +2 -0
- package/dist/lib/setup/providerGlyphs.d.ts +19 -0
- package/dist/lib/setup/providerGlyphs.js +42 -0
- package/dist/lib/setup/remoteRender.d.ts +31 -1
- package/dist/lib/setup/remoteRender.js +95 -4
- package/dist/lib/setup/sections/providers.d.ts +17 -0
- package/dist/lib/setup/sections/providers.js +307 -0
- package/dist/lib/setup/sections/routing.d.ts +2 -6
- package/dist/lib/setup/sections/routing.js +67 -82
- package/dist/lib/setup/sections/taskRoutingEditor.d.ts +13 -0
- package/dist/lib/setup/sections/taskRoutingEditor.js +139 -0
- package/dist/lib/setup/summary.d.ts +9 -0
- package/dist/lib/setup/summary.js +51 -37
- package/dist/lib/setup/ui/header.js +0 -1
- package/dist/lib/setup.d.ts +105 -15
- package/dist/lib/setup.js +747 -287
- package/dist/lib/setupKeys.d.ts +42 -0
- package/dist/lib/setupKeys.js +564 -0
- package/dist/lib/setupRemoteCommand.d.ts +4 -0
- package/dist/lib/setupRemoteCommand.js +28 -0
- package/dist/lib/setupRemotePullCommand.d.ts +5 -0
- package/dist/lib/setupRemotePullCommand.js +52 -0
- package/dist/lib/setupRemotePushCommand.d.ts +5 -0
- package/dist/lib/setupRemotePushCommand.js +57 -0
- package/dist/lib/setupRemoteResolveCommand.d.ts +4 -0
- package/dist/lib/setupRemoteResolveCommand.js +48 -0
- package/dist/lib/setupRemoteStatusCommand.d.ts +4 -0
- package/dist/lib/setupRemoteStatusCommand.js +73 -0
- package/dist/lib/setupRemoteSyncCommand.d.ts +6 -0
- package/dist/lib/setupRemoteSyncCommand.js +65 -0
- package/dist/lib/setupSyncProjectsCommand.d.ts +4 -0
- package/dist/lib/setupSyncProjectsCommand.js +292 -0
- package/dist/lib/staleCommand.d.ts +8 -0
- package/dist/lib/staleCommand.js +34 -0
- package/dist/lib/statsCommand.d.ts +6 -0
- package/dist/lib/statsCommand.js +142 -0
- package/dist/lib/statusCommand.d.ts +18 -0
- package/dist/lib/statusCommand.js +250 -0
- package/dist/lib/storesCommand.d.ts +2 -0
- package/dist/lib/storesCommand.js +4 -0
- package/dist/lib/syncClient.d.ts +41 -0
- package/dist/lib/syncClient.js +234 -0
- package/dist/lib/syncCommand.d.ts +6 -0
- package/dist/lib/syncCommand.js +57 -0
- package/dist/lib/syncDoctorCommand.d.ts +5 -0
- package/dist/lib/syncDoctorCommand.js +100 -0
- package/dist/lib/syncIngest.d.ts +30 -0
- package/dist/lib/syncIngest.js +175 -0
- package/dist/lib/syncIngestLaunchd.d.ts +8 -0
- package/dist/lib/syncIngestLaunchd.js +93 -0
- package/dist/lib/syncIngestStartup.d.ts +5 -0
- package/dist/lib/syncIngestStartup.js +29 -0
- package/dist/lib/syncIngestSystemd.d.ts +10 -0
- package/dist/lib/syncIngestSystemd.js +97 -0
- package/dist/lib/syncIngestTimer.d.ts +8 -0
- package/dist/lib/syncIngestTimer.js +27 -0
- package/dist/lib/syncIngestTimerCommand.d.ts +7 -0
- package/dist/lib/syncIngestTimerCommand.js +83 -0
- package/dist/lib/syncLock.d.ts +6 -0
- package/dist/lib/syncLock.js +74 -0
- package/dist/lib/syncSnapshot.d.ts +32 -0
- package/dist/lib/syncSnapshot.js +188 -0
- package/dist/lib/syncStaging.d.ts +79 -0
- package/dist/lib/syncStaging.js +237 -0
- package/dist/lib/tagsAddCommand.d.ts +8 -0
- package/dist/lib/tagsAddCommand.js +18 -0
- package/dist/lib/tagsCommand.d.ts +4 -0
- package/dist/lib/tagsCommand.js +16 -0
- package/dist/lib/timelineCommand.d.ts +7 -0
- package/dist/lib/timelineCommand.js +49 -0
- package/dist/lib/traceCommand.d.ts +6 -0
- package/dist/lib/traceCommand.js +39 -0
- package/dist/lib/traverseCommand.d.ts +6 -0
- package/dist/lib/traverseCommand.js +58 -0
- package/dist/lib/updateCommand.d.ts +13 -0
- package/dist/lib/updateCommand.js +67 -0
- package/dist/lib/updateStatusCommand.d.ts +5 -0
- package/dist/lib/updateStatusCommand.js +38 -0
- package/dist/lib/webAddCommand.d.ts +8 -0
- package/dist/lib/webAddCommand.js +55 -0
- package/dist/lib/webBuildCommand.d.ts +10 -0
- package/dist/lib/webBuildCommand.js +65 -0
- package/dist/lib/webBuildIndexCommand.d.ts +8 -0
- package/dist/lib/webBuildIndexCommand.js +37 -0
- package/dist/lib/webIndex.js +0 -1
- package/dist/lib/webIngestCommand.d.ts +11 -0
- package/dist/lib/webIngestCommand.js +51 -0
- package/dist/lib/webInitCommand.d.ts +9 -0
- package/dist/lib/webInitCommand.js +167 -0
- package/dist/lib/webRemoveCommand.d.ts +5 -0
- package/dist/lib/webRemoveCommand.js +41 -0
- package/dist/lib/webStatusCommand.d.ts +5 -0
- package/dist/lib/webStatusCommand.js +94 -0
- package/dist/lib/webUpdateCommand.d.ts +7 -0
- package/dist/lib/webUpdateCommand.js +72 -0
- package/dist/lib/workingSetCommand.d.ts +6 -0
- package/dist/lib/workingSetCommand.js +37 -0
- package/dist/sandbox/client.js +1 -1
- package/dist/sandbox/manager.js +1 -14
- package/dist/sandbox/server.js +3 -5
- package/package.json +6 -2
package/dist/lib/dream.js
CHANGED
|
@@ -18,10 +18,12 @@
|
|
|
18
18
|
* - Uses cheap/local LLM (configurable, defaults to Ollama)
|
|
19
19
|
*/
|
|
20
20
|
import os from "os";
|
|
21
|
-
import {
|
|
21
|
+
import { getProviderModel } from "./config.js";
|
|
22
|
+
import { createProvider } from "./llm.js";
|
|
22
23
|
import { notifyDesktop } from "./desktopNotify.js";
|
|
23
24
|
import { syncConfidenceToDb, auditToDb } from "./dbWrite.js";
|
|
24
25
|
import { logError } from "./log.js";
|
|
26
|
+
import { estimateCost, acquireDreamLock, estimateTokens, fingerprintMemories, memoryWatermark, readDreamState, writeDreamState, } from "./dreamRunLog.js";
|
|
25
27
|
/** Layer 4 alert threshold: fire desktop notification at this many consecutive provider failures. */
|
|
26
28
|
const DREAM_FAILURE_NOTIFY_THRESHOLD = 3;
|
|
27
29
|
export const DEFAULT_DREAM_CONFIG = {
|
|
@@ -34,6 +36,11 @@ export const DEFAULT_DREAM_CONFIG = {
|
|
|
34
36
|
generateSummaries: true,
|
|
35
37
|
discoverRelationships: true,
|
|
36
38
|
minMemories: 10,
|
|
39
|
+
schedule: { startHour: 2, endHour: 5 },
|
|
40
|
+
systemIdleMinutes: 30,
|
|
41
|
+
minNewMemoriesToDream: 10,
|
|
42
|
+
minHoursBetweenRuns: 20,
|
|
43
|
+
maxLLMCallsPerRun: 12,
|
|
37
44
|
};
|
|
38
45
|
// ─── Decay Constants ─────────────────────────────────────────────────────
|
|
39
46
|
const DECAY_LAMBDA = 0.005;
|
|
@@ -46,16 +53,37 @@ export class GnosysDreamEngine {
|
|
|
46
53
|
provider = null;
|
|
47
54
|
abortRequested = false;
|
|
48
55
|
startTime = 0;
|
|
49
|
-
|
|
56
|
+
trigger;
|
|
57
|
+
machineId;
|
|
58
|
+
dreamState = readDreamState();
|
|
59
|
+
pendingFingerprints = {};
|
|
60
|
+
llmCallsMade = 0;
|
|
61
|
+
constructor(db, config, dreamConfig, options) {
|
|
50
62
|
this.db = db;
|
|
51
63
|
this.config = config;
|
|
52
|
-
this.dreamConfig = {
|
|
64
|
+
this.dreamConfig = {
|
|
65
|
+
...DEFAULT_DREAM_CONFIG,
|
|
66
|
+
...dreamConfig,
|
|
67
|
+
schedule: { ...DEFAULT_DREAM_CONFIG.schedule, ...(dreamConfig?.schedule ?? {}) },
|
|
68
|
+
};
|
|
69
|
+
this.trigger = options?.trigger ?? "manual";
|
|
70
|
+
this.machineId = options?.machineId;
|
|
53
71
|
// Initialize LLM provider for dream operations.
|
|
54
72
|
// v5.4.2: Failure here is no longer silent — when dream tries to actually
|
|
55
73
|
// run (in dream()), we record the unavailability to audit_log so the
|
|
56
74
|
// user gets visibility (Layer 2 alert) and can react via the dashboard.
|
|
57
75
|
try {
|
|
58
|
-
|
|
76
|
+
const provider = this.dreamConfig.provider;
|
|
77
|
+
let model = this.dreamConfig.model;
|
|
78
|
+
if (!model) {
|
|
79
|
+
try {
|
|
80
|
+
model = getProviderModel(this.config, provider);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
model = "";
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
this.provider = createProvider(provider, model, this.config);
|
|
59
87
|
}
|
|
60
88
|
catch (err) {
|
|
61
89
|
this.provider = null;
|
|
@@ -64,6 +92,136 @@ export class GnosysDreamEngine {
|
|
|
64
92
|
}
|
|
65
93
|
/** Captured at construction if getLLMProvider throws. Used in dream() to write a Layer 2 audit entry. */
|
|
66
94
|
providerInitError = null;
|
|
95
|
+
createPhase(name) {
|
|
96
|
+
return {
|
|
97
|
+
name,
|
|
98
|
+
status: "ran",
|
|
99
|
+
durationMs: 0,
|
|
100
|
+
memoryIdsTouched: [],
|
|
101
|
+
llmCallsMade: 0,
|
|
102
|
+
llmCallsSkipped: 0,
|
|
103
|
+
estimatedInputTokens: 0,
|
|
104
|
+
estimatedOutputTokens: 0,
|
|
105
|
+
estimatedCostUsd: 0,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
finishPhase(phase, startedAtMs) {
|
|
109
|
+
phase.durationMs = Date.now() - startedAtMs;
|
|
110
|
+
phase.memoryIdsTouched = Array.from(new Set(phase.memoryIdsTouched));
|
|
111
|
+
phase.estimatedCostUsd = Math.round(phase.estimatedCostUsd * 1_000_000) / 1_000_000;
|
|
112
|
+
this.checkpointFingerprints();
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* v5.12.1 crash safety: persist analyzed fingerprints at every phase
|
|
116
|
+
* boundary, not only in finalize(). A crash mid-run previously lost all
|
|
117
|
+
* pendingFingerprints, so the next run re-analyzed (and re-paid for) the
|
|
118
|
+
* same memory sets and could double-create summaries. Checkpointing only
|
|
119
|
+
* merges fingerprints — lastRunAt / watermarks remain finalize()'s job.
|
|
120
|
+
*/
|
|
121
|
+
checkpointFingerprints() {
|
|
122
|
+
if (Object.keys(this.pendingFingerprints).length === 0)
|
|
123
|
+
return;
|
|
124
|
+
try {
|
|
125
|
+
writeDreamState({
|
|
126
|
+
...this.dreamState,
|
|
127
|
+
analyzedFingerprints: {
|
|
128
|
+
...this.dreamState.analyzedFingerprints,
|
|
129
|
+
...this.pendingFingerprints,
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// Best-effort: a failed checkpoint only costs re-analysis on resume.
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
addTouched(phase, memoryIds) {
|
|
138
|
+
for (const id of memoryIds) {
|
|
139
|
+
if (id)
|
|
140
|
+
phase.memoryIdsTouched.push(id);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
recordLLMSkip(phase, label, reason, memoryIds = [], fingerprint) {
|
|
144
|
+
phase.llmCallsSkipped++;
|
|
145
|
+
this.llmCalls.push({
|
|
146
|
+
phase: phase.name,
|
|
147
|
+
label,
|
|
148
|
+
status: "skipped",
|
|
149
|
+
reason,
|
|
150
|
+
provider: this.dreamConfig.provider,
|
|
151
|
+
model: this.dreamConfig.model || this.provider?.model || getProviderModel(this.config, this.dreamConfig.provider),
|
|
152
|
+
memoryIds,
|
|
153
|
+
fingerprint,
|
|
154
|
+
estimatedInputTokens: 0,
|
|
155
|
+
estimatedOutputTokens: 0,
|
|
156
|
+
estimatedCostUsd: 0,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
llmCalls = [];
|
|
160
|
+
async generateWithAccounting(phase, label, prompt, maxTokens, memoryIds, fingerprint) {
|
|
161
|
+
if (!this.provider) {
|
|
162
|
+
this.recordLLMSkip(phase, label, "provider unavailable", memoryIds, fingerprint);
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
if (fingerprint && (this.dreamState.analyzedFingerprints[fingerprint] || this.pendingFingerprints[fingerprint])) {
|
|
166
|
+
this.recordLLMSkip(phase, label, "already analyzed fingerprint", memoryIds, fingerprint);
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
if (this.llmCallsMade >= this.dreamConfig.maxLLMCallsPerRun) {
|
|
170
|
+
this.recordLLMSkip(phase, label, "maxLLMCallsPerRun reached", memoryIds, fingerprint);
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
const inputTokens = estimateTokens(prompt);
|
|
174
|
+
this.llmCallsMade++;
|
|
175
|
+
try {
|
|
176
|
+
const response = await this.provider.generate(prompt, { maxTokens });
|
|
177
|
+
const outputTokens = estimateTokens(response);
|
|
178
|
+
const cost = estimateCost(this.provider.model, inputTokens, outputTokens);
|
|
179
|
+
phase.llmCallsMade++;
|
|
180
|
+
phase.estimatedInputTokens += inputTokens;
|
|
181
|
+
phase.estimatedOutputTokens += outputTokens;
|
|
182
|
+
phase.estimatedCostUsd += cost;
|
|
183
|
+
this.llmCalls.push({
|
|
184
|
+
phase: phase.name,
|
|
185
|
+
label,
|
|
186
|
+
status: "made",
|
|
187
|
+
provider: this.provider.name,
|
|
188
|
+
model: this.provider.model,
|
|
189
|
+
memoryIds,
|
|
190
|
+
fingerprint,
|
|
191
|
+
estimatedInputTokens: inputTokens,
|
|
192
|
+
estimatedOutputTokens: outputTokens,
|
|
193
|
+
estimatedCostUsd: cost,
|
|
194
|
+
});
|
|
195
|
+
if (fingerprint && response) {
|
|
196
|
+
this.pendingFingerprints[fingerprint] = {
|
|
197
|
+
kind: phase.name === "relationships" ? "relationship" : phase.name === "summaries" ? "summary" : "critique",
|
|
198
|
+
lastAnalyzedAt: new Date().toISOString(),
|
|
199
|
+
memoryIds,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
return response;
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
phase.llmCallsMade++;
|
|
206
|
+
const cost = estimateCost(this.provider.model, inputTokens, 0);
|
|
207
|
+
phase.estimatedInputTokens += inputTokens;
|
|
208
|
+
phase.estimatedCostUsd += cost;
|
|
209
|
+
this.llmCalls.push({
|
|
210
|
+
phase: phase.name,
|
|
211
|
+
label,
|
|
212
|
+
status: "failed",
|
|
213
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
214
|
+
provider: this.provider.name,
|
|
215
|
+
model: this.provider.model,
|
|
216
|
+
memoryIds,
|
|
217
|
+
fingerprint,
|
|
218
|
+
estimatedInputTokens: inputTokens,
|
|
219
|
+
estimatedOutputTokens: 0,
|
|
220
|
+
estimatedCostUsd: cost,
|
|
221
|
+
});
|
|
222
|
+
throw err;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
67
225
|
/** Expose the local DB so DreamScheduler can read designation meta. */
|
|
68
226
|
getDb() {
|
|
69
227
|
return this.db;
|
|
@@ -100,9 +258,16 @@ export class GnosysDreamEngine {
|
|
|
100
258
|
async dream(onProgress) {
|
|
101
259
|
this.startTime = Date.now();
|
|
102
260
|
this.abortRequested = false;
|
|
261
|
+
this.llmCallsMade = 0;
|
|
262
|
+
this.llmCalls = [];
|
|
263
|
+
this.pendingFingerprints = {};
|
|
264
|
+
this.dreamState = readDreamState();
|
|
103
265
|
const log = onProgress || (() => { });
|
|
266
|
+
const startedAt = new Date().toISOString();
|
|
104
267
|
const report = {
|
|
105
|
-
|
|
268
|
+
id: `dream-${Date.parse(startedAt)}-${Math.random().toString(36).slice(2, 8)}`,
|
|
269
|
+
trigger: this.trigger,
|
|
270
|
+
startedAt,
|
|
106
271
|
finishedAt: "",
|
|
107
272
|
durationMs: 0,
|
|
108
273
|
decayUpdated: 0,
|
|
@@ -113,6 +278,27 @@ export class GnosysDreamEngine {
|
|
|
113
278
|
duplicatesFound: 0,
|
|
114
279
|
errors: [],
|
|
115
280
|
aborted: false,
|
|
281
|
+
machine: { hostname: os.hostname(), machineId: this.machineId },
|
|
282
|
+
provider: this.dreamConfig.provider,
|
|
283
|
+
model: this.dreamConfig.model || this.provider?.model,
|
|
284
|
+
phases: [],
|
|
285
|
+
llmCalls: [],
|
|
286
|
+
totals: {
|
|
287
|
+
llmCallsMade: 0,
|
|
288
|
+
llmCallsSkipped: 0,
|
|
289
|
+
estimatedInputTokens: 0,
|
|
290
|
+
estimatedOutputTokens: 0,
|
|
291
|
+
estimatedCostUsd: 0,
|
|
292
|
+
},
|
|
293
|
+
effectiveness: {
|
|
294
|
+
usefulOutputScore: 0,
|
|
295
|
+
costPerUsefulOutput: null,
|
|
296
|
+
decaysApplied: 0,
|
|
297
|
+
summariesGenerated: 0,
|
|
298
|
+
summariesUpdated: 0,
|
|
299
|
+
reviewSuggestions: 0,
|
|
300
|
+
relationshipsDiscovered: 0,
|
|
301
|
+
},
|
|
116
302
|
};
|
|
117
303
|
if (!this.db.isAvailable() || !this.db.isMigrated()) {
|
|
118
304
|
report.errors.push("gnosys.db not available or not migrated");
|
|
@@ -161,13 +347,21 @@ export class GnosysDreamEngine {
|
|
|
161
347
|
}
|
|
162
348
|
// ─── Phase 1: Confidence Decay Sweep ─────────────────────────────────
|
|
163
349
|
log("decay", "Phase 1: Confidence decay sweep...");
|
|
350
|
+
const decayPhase = this.createPhase("decay");
|
|
351
|
+
const decayStart = Date.now();
|
|
352
|
+
report.phases.push(decayPhase);
|
|
164
353
|
try {
|
|
165
|
-
|
|
354
|
+
const decayResult = this.decaySweep();
|
|
355
|
+
report.decayUpdated = decayResult.count;
|
|
356
|
+
this.addTouched(decayPhase, decayResult.memoryIds);
|
|
166
357
|
log("decay", `Updated ${report.decayUpdated} memories`);
|
|
167
358
|
}
|
|
168
359
|
catch (err) {
|
|
169
360
|
report.errors.push(`Decay sweep: ${err instanceof Error ? err.message : String(err)}`);
|
|
170
361
|
}
|
|
362
|
+
finally {
|
|
363
|
+
this.finishPhase(decayPhase, decayStart);
|
|
364
|
+
}
|
|
171
365
|
let check = this.shouldStop();
|
|
172
366
|
if (check.stop) {
|
|
173
367
|
report.aborted = true;
|
|
@@ -177,13 +371,20 @@ export class GnosysDreamEngine {
|
|
|
177
371
|
// ─── Phase 2: Self-Critique (Review Suggestions) ─────────────────────
|
|
178
372
|
if (this.dreamConfig.selfCritique) {
|
|
179
373
|
log("critique", "Phase 2: Self-critique...");
|
|
374
|
+
const critiquePhase = this.createPhase("critique");
|
|
375
|
+
const critiqueStart = Date.now();
|
|
376
|
+
report.phases.push(critiquePhase);
|
|
180
377
|
try {
|
|
181
|
-
report.reviewSuggestions = await this.selfCritique(log);
|
|
378
|
+
report.reviewSuggestions = await this.selfCritique(log, critiquePhase);
|
|
379
|
+
this.addTouched(critiquePhase, report.reviewSuggestions.map((s) => s.memoryId));
|
|
182
380
|
log("critique", `Generated ${report.reviewSuggestions.length} review suggestions`);
|
|
183
381
|
}
|
|
184
382
|
catch (err) {
|
|
185
383
|
report.errors.push(`Self-critique: ${err instanceof Error ? err.message : String(err)}`);
|
|
186
384
|
}
|
|
385
|
+
finally {
|
|
386
|
+
this.finishPhase(critiquePhase, critiqueStart);
|
|
387
|
+
}
|
|
187
388
|
check = this.shouldStop();
|
|
188
389
|
if (check.stop) {
|
|
189
390
|
report.aborted = true;
|
|
@@ -194,15 +395,22 @@ export class GnosysDreamEngine {
|
|
|
194
395
|
// ─── Phase 3: Summary Generation ─────────────────────────────────────
|
|
195
396
|
if (this.dreamConfig.generateSummaries && this.provider) {
|
|
196
397
|
log("summaries", "Phase 3: Summary generation...");
|
|
398
|
+
const summariesPhase = this.createPhase("summaries");
|
|
399
|
+
const summariesStart = Date.now();
|
|
400
|
+
report.phases.push(summariesPhase);
|
|
197
401
|
try {
|
|
198
|
-
const summaryResult = await this.generateSummaries(log);
|
|
402
|
+
const summaryResult = await this.generateSummaries(log, summariesPhase);
|
|
199
403
|
report.summariesGenerated = summaryResult.generated;
|
|
200
404
|
report.summariesUpdated = summaryResult.updated;
|
|
405
|
+
this.addTouched(summariesPhase, summaryResult.memoryIds);
|
|
201
406
|
log("summaries", `Generated ${summaryResult.generated}, updated ${summaryResult.updated}`);
|
|
202
407
|
}
|
|
203
408
|
catch (err) {
|
|
204
409
|
report.errors.push(`Summary generation: ${err instanceof Error ? err.message : String(err)}`);
|
|
205
410
|
}
|
|
411
|
+
finally {
|
|
412
|
+
this.finishPhase(summariesPhase, summariesStart);
|
|
413
|
+
}
|
|
206
414
|
check = this.shouldStop();
|
|
207
415
|
if (check.stop) {
|
|
208
416
|
report.aborted = true;
|
|
@@ -213,19 +421,73 @@ export class GnosysDreamEngine {
|
|
|
213
421
|
// ─── Phase 4: Relationship Discovery ─────────────────────────────────
|
|
214
422
|
if (this.dreamConfig.discoverRelationships && this.provider) {
|
|
215
423
|
log("relationships", "Phase 4: Relationship discovery...");
|
|
424
|
+
const relationshipsPhase = this.createPhase("relationships");
|
|
425
|
+
const relationshipsStart = Date.now();
|
|
426
|
+
report.phases.push(relationshipsPhase);
|
|
216
427
|
try {
|
|
217
|
-
|
|
428
|
+
const relationshipsResult = await this.discoverRelationships(log, relationshipsPhase);
|
|
429
|
+
report.relationshipsDiscovered = relationshipsResult.count;
|
|
430
|
+
this.addTouched(relationshipsPhase, relationshipsResult.memoryIds);
|
|
218
431
|
log("relationships", `Discovered ${report.relationshipsDiscovered} new relationships`);
|
|
219
432
|
}
|
|
220
433
|
catch (err) {
|
|
221
434
|
report.errors.push(`Relationship discovery: ${err instanceof Error ? err.message : String(err)}`);
|
|
222
435
|
}
|
|
436
|
+
finally {
|
|
437
|
+
this.finishPhase(relationshipsPhase, relationshipsStart);
|
|
438
|
+
}
|
|
223
439
|
}
|
|
224
440
|
return this.finalize(report);
|
|
225
441
|
}
|
|
226
442
|
finalize(report) {
|
|
227
443
|
report.finishedAt = new Date().toISOString();
|
|
228
444
|
report.durationMs = Date.now() - this.startTime;
|
|
445
|
+
report.llmCalls = this.llmCalls;
|
|
446
|
+
report.totals = this.llmCalls.reduce((totals, call) => {
|
|
447
|
+
if (call.status === "made" || call.status === "failed")
|
|
448
|
+
totals.llmCallsMade++;
|
|
449
|
+
if (call.status === "skipped")
|
|
450
|
+
totals.llmCallsSkipped++;
|
|
451
|
+
totals.estimatedInputTokens += call.estimatedInputTokens;
|
|
452
|
+
totals.estimatedOutputTokens += call.estimatedOutputTokens;
|
|
453
|
+
totals.estimatedCostUsd += call.estimatedCostUsd;
|
|
454
|
+
return totals;
|
|
455
|
+
}, {
|
|
456
|
+
llmCallsMade: 0,
|
|
457
|
+
llmCallsSkipped: 0,
|
|
458
|
+
estimatedInputTokens: 0,
|
|
459
|
+
estimatedOutputTokens: 0,
|
|
460
|
+
estimatedCostUsd: 0,
|
|
461
|
+
});
|
|
462
|
+
report.totals.estimatedCostUsd = Math.round(report.totals.estimatedCostUsd * 1_000_000) / 1_000_000;
|
|
463
|
+
const usefulOutputScore = report.decayUpdated +
|
|
464
|
+
report.summariesGenerated * 5 +
|
|
465
|
+
report.summariesUpdated * 3 +
|
|
466
|
+
report.relationshipsDiscovered * 2;
|
|
467
|
+
report.effectiveness = {
|
|
468
|
+
usefulOutputScore,
|
|
469
|
+
costPerUsefulOutput: usefulOutputScore > 0
|
|
470
|
+
? Math.round((report.totals.estimatedCostUsd / usefulOutputScore) * 1_000_000) / 1_000_000
|
|
471
|
+
: null,
|
|
472
|
+
decaysApplied: report.decayUpdated,
|
|
473
|
+
summariesGenerated: report.summariesGenerated,
|
|
474
|
+
summariesUpdated: report.summariesUpdated,
|
|
475
|
+
reviewSuggestions: report.reviewSuggestions.length,
|
|
476
|
+
relationshipsDiscovered: report.relationshipsDiscovered,
|
|
477
|
+
};
|
|
478
|
+
const memories = this.db.isAvailable() ? this.db.getActiveMemories() : [];
|
|
479
|
+
const watermark = memoryWatermark(memories);
|
|
480
|
+
writeDreamState({
|
|
481
|
+
...this.dreamState,
|
|
482
|
+
lastRunAt: report.finishedAt,
|
|
483
|
+
lastSuccessfulRunAt: report.errors.length === 0 && !report.aborted ? report.finishedAt : this.dreamState.lastSuccessfulRunAt,
|
|
484
|
+
lastMemoryCount: watermark.count,
|
|
485
|
+
lastMemoryMaxModified: watermark.maxModified,
|
|
486
|
+
analyzedFingerprints: {
|
|
487
|
+
...this.dreamState.analyzedFingerprints,
|
|
488
|
+
...this.pendingFingerprints,
|
|
489
|
+
},
|
|
490
|
+
});
|
|
229
491
|
// v5.4.2: A run is considered "successful with LLM work" if any of the
|
|
230
492
|
// LLM-dependent counters moved. Resetting the consecutive-failure count
|
|
231
493
|
// here ensures Layer 4 doesn't keep firing once dream is healthy again.
|
|
@@ -241,6 +503,10 @@ export class GnosysDreamEngine {
|
|
|
241
503
|
summariesGenerated: report.summariesGenerated,
|
|
242
504
|
reviewSuggestions: report.reviewSuggestions.length,
|
|
243
505
|
relationshipsDiscovered: report.relationshipsDiscovered,
|
|
506
|
+
llmCallsMade: report.totals.llmCallsMade,
|
|
507
|
+
llmCallsSkipped: report.totals.llmCallsSkipped,
|
|
508
|
+
estimatedCostUsd: report.totals.estimatedCostUsd,
|
|
509
|
+
usefulOutputScore: report.effectiveness.usefulOutputScore,
|
|
244
510
|
errors: report.errors.length,
|
|
245
511
|
aborted: report.aborted,
|
|
246
512
|
providerUnreachable: !this.provider,
|
|
@@ -257,9 +523,9 @@ export class GnosysDreamEngine {
|
|
|
257
523
|
*/
|
|
258
524
|
decaySweep() {
|
|
259
525
|
const now = new Date();
|
|
260
|
-
const today = now.toISOString().split("T")[0];
|
|
261
526
|
const memories = this.db.getActiveMemories();
|
|
262
527
|
let updated = 0;
|
|
528
|
+
const memoryIds = [];
|
|
263
529
|
for (const mem of memories) {
|
|
264
530
|
const lastReinforced = mem.last_reinforced || mem.modified || mem.created;
|
|
265
531
|
const lastDate = new Date(lastReinforced);
|
|
@@ -272,16 +538,17 @@ export class GnosysDreamEngine {
|
|
|
272
538
|
if (Math.abs(rounded - mem.confidence) > 0.01) {
|
|
273
539
|
syncConfidenceToDb(this.db, mem.id, rounded);
|
|
274
540
|
updated++;
|
|
541
|
+
memoryIds.push(mem.id);
|
|
275
542
|
}
|
|
276
543
|
}
|
|
277
|
-
return updated;
|
|
544
|
+
return { count: updated, memoryIds };
|
|
278
545
|
}
|
|
279
546
|
// ─── Phase 2: Self-Critique ────────────────────────────────────────────
|
|
280
547
|
/**
|
|
281
548
|
* Score memories and generate review suggestions.
|
|
282
549
|
* NEVER deletes or archives — only flags for human review.
|
|
283
550
|
*/
|
|
284
|
-
async selfCritique(log) {
|
|
551
|
+
async selfCritique(log, phase) {
|
|
285
552
|
const suggestions = [];
|
|
286
553
|
const memories = this.db.getActiveMemories();
|
|
287
554
|
for (const mem of memories) {
|
|
@@ -308,7 +575,7 @@ export class GnosysDreamEngine {
|
|
|
308
575
|
if (check.stop)
|
|
309
576
|
break;
|
|
310
577
|
try {
|
|
311
|
-
const llmSuggestion = await this.llmCritique(mem);
|
|
578
|
+
const llmSuggestion = await this.llmCritique(mem, phase);
|
|
312
579
|
if (llmSuggestion) {
|
|
313
580
|
suggestions.push(llmSuggestion);
|
|
314
581
|
}
|
|
@@ -374,9 +641,10 @@ export class GnosysDreamEngine {
|
|
|
374
641
|
/**
|
|
375
642
|
* LLM-based critique for borderline memories.
|
|
376
643
|
*/
|
|
377
|
-
async llmCritique(mem) {
|
|
644
|
+
async llmCritique(mem, phase) {
|
|
378
645
|
if (!this.provider)
|
|
379
646
|
return null;
|
|
647
|
+
const fingerprint = fingerprintMemories("critique", [mem]);
|
|
380
648
|
const prompt = `You are a knowledge management quality reviewer. Evaluate this memory and decide if it needs attention.
|
|
381
649
|
|
|
382
650
|
Title: ${mem.title}
|
|
@@ -395,7 +663,9 @@ Respond with ONLY one of these JSON objects (no explanation):
|
|
|
395
663
|
- {"action": "needs-update", "reason": "..."} if content seems outdated
|
|
396
664
|
- {"action": "consider-merge", "reason": "..."} if it seems to overlap with other common knowledge`;
|
|
397
665
|
try {
|
|
398
|
-
const response = await this.
|
|
666
|
+
const response = await this.generateWithAccounting(phase, `critique:${mem.id}`, prompt, 200, [mem.id], fingerprint);
|
|
667
|
+
if (!response)
|
|
668
|
+
return null;
|
|
399
669
|
const jsonMatch = response.match(/\{[^}]+\}/);
|
|
400
670
|
if (!jsonMatch)
|
|
401
671
|
return null;
|
|
@@ -429,12 +699,13 @@ Respond with ONLY one of these JSON objects (no explanation):
|
|
|
429
699
|
* Generate or update hierarchical summaries per category.
|
|
430
700
|
* Uses LLM to synthesize category-level overviews.
|
|
431
701
|
*/
|
|
432
|
-
async generateSummaries(log) {
|
|
702
|
+
async generateSummaries(log, phase) {
|
|
433
703
|
if (!this.provider)
|
|
434
|
-
return { generated: 0, updated: 0 };
|
|
704
|
+
return { generated: 0, updated: 0, memoryIds: [] };
|
|
435
705
|
const categories = this.db.getCategories();
|
|
436
706
|
let generated = 0;
|
|
437
707
|
let updated = 0;
|
|
708
|
+
const touched = [];
|
|
438
709
|
for (const category of categories) {
|
|
439
710
|
const check = this.shouldStop();
|
|
440
711
|
if (check.stop)
|
|
@@ -449,12 +720,15 @@ Respond with ONLY one of these JSON objects (no explanation):
|
|
|
449
720
|
const currentIds = memories.map((m) => m.id);
|
|
450
721
|
const unchanged = existingIds.length === currentIds.length &&
|
|
451
722
|
existingIds.every((id) => currentIds.includes(id));
|
|
452
|
-
if (unchanged)
|
|
723
|
+
if (unchanged) {
|
|
724
|
+
phase.llmCallsSkipped++;
|
|
725
|
+
phase.reason = phase.reason || "unchanged summaries skipped";
|
|
453
726
|
continue; // No new memories in this category
|
|
727
|
+
}
|
|
454
728
|
}
|
|
455
729
|
log("summaries", `Summarizing ${category} (${memories.length} memories)...`);
|
|
456
730
|
try {
|
|
457
|
-
const summary = await this.summarizeCategory(category, memories);
|
|
731
|
+
const summary = await this.summarizeCategory(category, memories, phase);
|
|
458
732
|
if (summary) {
|
|
459
733
|
const today = new Date().toISOString().split("T")[0];
|
|
460
734
|
const id = existing?.id || `summary-${category}-${today}`;
|
|
@@ -473,18 +747,19 @@ Respond with ONLY one of these JSON objects (no explanation):
|
|
|
473
747
|
else {
|
|
474
748
|
generated++;
|
|
475
749
|
}
|
|
750
|
+
touched.push(...memories.map((m) => m.id));
|
|
476
751
|
}
|
|
477
752
|
}
|
|
478
753
|
catch (err) {
|
|
479
754
|
log("summaries", `Failed to summarize ${category}: ${err instanceof Error ? err.message : String(err)}`);
|
|
480
755
|
}
|
|
481
756
|
}
|
|
482
|
-
return { generated, updated };
|
|
757
|
+
return { generated, updated, memoryIds: touched };
|
|
483
758
|
}
|
|
484
759
|
/**
|
|
485
760
|
* Use LLM to generate a category summary.
|
|
486
761
|
*/
|
|
487
|
-
async summarizeCategory(category, memories) {
|
|
762
|
+
async summarizeCategory(category, memories, phase) {
|
|
488
763
|
if (!this.provider)
|
|
489
764
|
return null;
|
|
490
765
|
// Build context from memories (truncate to fit context window)
|
|
@@ -506,7 +781,7 @@ ${memoryTexts}
|
|
|
506
781
|
|
|
507
782
|
Category summary:`;
|
|
508
783
|
try {
|
|
509
|
-
return await this.
|
|
784
|
+
return await this.generateWithAccounting(phase, `summary:${category}`, prompt, 1024, memories.map((m) => m.id), fingerprintMemories("summary", memories));
|
|
510
785
|
}
|
|
511
786
|
catch {
|
|
512
787
|
return null;
|
|
@@ -517,13 +792,14 @@ Category summary:`;
|
|
|
517
792
|
* Use LLM to discover relationships between memories.
|
|
518
793
|
* Only creates new edges — never removes existing ones.
|
|
519
794
|
*/
|
|
520
|
-
async discoverRelationships(log) {
|
|
795
|
+
async discoverRelationships(log, phase) {
|
|
521
796
|
if (!this.provider)
|
|
522
|
-
return 0;
|
|
797
|
+
return { count: 0, memoryIds: [] };
|
|
523
798
|
const memories = this.db.getActiveMemories();
|
|
524
799
|
if (memories.length < 3)
|
|
525
|
-
return 0;
|
|
800
|
+
return { count: 0, memoryIds: [] };
|
|
526
801
|
let discovered = 0;
|
|
802
|
+
const touched = new Set();
|
|
527
803
|
const today = new Date().toISOString().split("T")[0];
|
|
528
804
|
// Get existing relationships to avoid duplicates
|
|
529
805
|
const existingPairs = new Set();
|
|
@@ -548,7 +824,7 @@ Category summary:`;
|
|
|
548
824
|
const batchTitles = batch.map((m) => `[${m.id}] ${m.title}`).join(", ");
|
|
549
825
|
log("relationships", `Analyzing relationships for: ${batchTitles}`);
|
|
550
826
|
try {
|
|
551
|
-
const relationships = await this.findRelationships(batch, memoryIndex);
|
|
827
|
+
const relationships = await this.findRelationships(batch, memoryIndex, phase);
|
|
552
828
|
for (const rel of relationships) {
|
|
553
829
|
const key = `${rel.source_id}→${rel.target_id}→${rel.rel_type}`;
|
|
554
830
|
if (existingPairs.has(key))
|
|
@@ -563,18 +839,20 @@ Category summary:`;
|
|
|
563
839
|
});
|
|
564
840
|
existingPairs.add(key);
|
|
565
841
|
discovered++;
|
|
842
|
+
touched.add(rel.source_id);
|
|
843
|
+
touched.add(rel.target_id);
|
|
566
844
|
}
|
|
567
845
|
}
|
|
568
846
|
catch (err) {
|
|
569
847
|
log("relationships", `Failed for batch: ${err instanceof Error ? err.message : String(err)}`);
|
|
570
848
|
}
|
|
571
849
|
}
|
|
572
|
-
return discovered;
|
|
850
|
+
return { count: discovered, memoryIds: Array.from(touched) };
|
|
573
851
|
}
|
|
574
852
|
/**
|
|
575
853
|
* Use LLM to find relationships for a batch of source memories.
|
|
576
854
|
*/
|
|
577
|
-
async findRelationships(sources, memoryIndex) {
|
|
855
|
+
async findRelationships(sources, memoryIndex, phase) {
|
|
578
856
|
if (!this.provider)
|
|
579
857
|
return [];
|
|
580
858
|
const sourceContext = sources
|
|
@@ -594,7 +872,9 @@ For each relationship found, output a JSON array of objects with: source_id, tar
|
|
|
594
872
|
Only output relationships with confidence >= 0.7. Do NOT create self-referencing relationships.
|
|
595
873
|
Output ONLY the JSON array, no explanation.`;
|
|
596
874
|
try {
|
|
597
|
-
const response = await this.
|
|
875
|
+
const response = await this.generateWithAccounting(phase, `relationships:${sources.map((s) => s.id).join(",")}`, prompt, 1024, sources.map((s) => s.id), fingerprintMemories("relationship", sources));
|
|
876
|
+
if (!response)
|
|
877
|
+
return [];
|
|
598
878
|
// Extract JSON array from response
|
|
599
879
|
const jsonMatch = response.match(/\[[\s\S]*\]/);
|
|
600
880
|
if (!jsonMatch)
|
|
@@ -730,6 +1010,15 @@ export class DreamScheduler {
|
|
|
730
1010
|
const idleMs = Date.now() - this.lastActivity;
|
|
731
1011
|
const idleMinutes = idleMs / 60_000;
|
|
732
1012
|
if (idleMinutes >= this.config.idleMinutes) {
|
|
1013
|
+
// v5.12.1: the in-memory `running` flag does not survive a sandbox
|
|
1014
|
+
// restart and cannot see a concurrent manual `gnosys dream`. Tie the
|
|
1015
|
+
// scheduler to the same cross-process file lock the CLI uses.
|
|
1016
|
+
const lock = acquireDreamLock();
|
|
1017
|
+
if (!lock.acquired) {
|
|
1018
|
+
console.error(`[dream] scheduler skipped: ${lock.reason}`);
|
|
1019
|
+
this.lastActivity = Date.now(); // back off a full idle window
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
733
1022
|
this.running = true;
|
|
734
1023
|
try {
|
|
735
1024
|
this.currentDream = this.engine.dream((phase, detail) => {
|
|
@@ -746,6 +1035,7 @@ export class DreamScheduler {
|
|
|
746
1035
|
this.running = false;
|
|
747
1036
|
this.currentDream = null;
|
|
748
1037
|
this.lastActivity = Date.now(); // Reset idle timer after dream
|
|
1038
|
+
lock.release();
|
|
749
1039
|
}
|
|
750
1040
|
}
|
|
751
1041
|
}
|
|
@@ -769,7 +1059,7 @@ export function formatDreamReport(report) {
|
|
|
769
1059
|
lines.push(`Started: ${report.startedAt}`);
|
|
770
1060
|
lines.push(`Finished: ${report.finishedAt}`);
|
|
771
1061
|
if (report.aborted) {
|
|
772
|
-
lines.push(
|
|
1062
|
+
lines.push(`Aborted: ${report.abortReason}`);
|
|
773
1063
|
}
|
|
774
1064
|
lines.push("");
|
|
775
1065
|
lines.push("Results:");
|
|
@@ -778,6 +1068,10 @@ export function formatDreamReport(report) {
|
|
|
778
1068
|
lines.push(` Summaries updated: ${report.summariesUpdated}`);
|
|
779
1069
|
lines.push(` Relationships discovered: ${report.relationshipsDiscovered}`);
|
|
780
1070
|
lines.push(` Duplicates flagged: ${report.duplicatesFound}`);
|
|
1071
|
+
if (report.totals) {
|
|
1072
|
+
lines.push(` LLM calls: ${report.totals.llmCallsMade} made, ${report.totals.llmCallsSkipped} skipped`);
|
|
1073
|
+
lines.push(` Estimated cost: $${report.totals.estimatedCostUsd.toFixed(6)}`);
|
|
1074
|
+
}
|
|
781
1075
|
lines.push("");
|
|
782
1076
|
if (report.reviewSuggestions.length > 0) {
|
|
783
1077
|
lines.push(`Review Suggestions (${report.reviewSuggestions.length}):`);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type DreamCommandOptions = {
|
|
2
|
+
maxRuntime?: string;
|
|
3
|
+
critique?: boolean;
|
|
4
|
+
summaries?: boolean;
|
|
5
|
+
relationships?: boolean;
|
|
6
|
+
json?: boolean;
|
|
7
|
+
force?: boolean;
|
|
8
|
+
scheduled?: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare function runDreamCommand(opts: DreamCommandOptions): Promise<void>;
|