@remnic/core 9.3.630 → 9.3.631
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/access-cli.js +15 -13
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +4 -4
- package/dist/access-http.js +7 -6
- package/dist/access-mcp.d.ts +4 -4
- package/dist/access-mcp.js +6 -5
- package/dist/{access-service-C4v-eFjB.d.ts → access-service-C9_EpVHd.d.ts} +2 -2
- package/dist/access-service.d.ts +4 -4
- package/dist/access-service.js +5 -4
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +1 -1
- package/dist/auto-sync-RFADEHIQ.js +75 -0
- package/dist/auto-sync-RFADEHIQ.js.map +1 -0
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +3 -3
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +3 -2
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/calibration.d.ts +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +4 -3
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/{chunk-BWK5EEKS.js → chunk-242XFZ36.js} +2 -2
- package/dist/{chunk-K3BTOW7N.js → chunk-32U3N7H5.js} +3 -3
- package/dist/{chunk-5S6IREG3.js → chunk-3RDYU3JS.js} +3 -3
- package/dist/{chunk-SACS6KE6.js → chunk-4S3N6HFG.js} +2 -2
- package/dist/{chunk-VUTPRX7K.js → chunk-5PT5I6JQ.js} +14 -14
- package/dist/{chunk-2VJ7AJFX.js → chunk-7A2QKUUA.js} +2 -2
- package/dist/{chunk-EORL2IDM.js → chunk-7H5WCPBS.js} +58 -5
- package/dist/{chunk-EORL2IDM.js.map → chunk-7H5WCPBS.js.map} +1 -1
- package/dist/{chunk-NRQJBK36.js → chunk-C4KKM62E.js} +2 -2
- package/dist/{chunk-GXWFZYSR.js → chunk-CMN5AWAZ.js} +2 -2
- package/dist/{chunk-F6USGHMO.js → chunk-DOBJH4I6.js} +4 -4
- package/dist/{chunk-ADOD7PJC.js → chunk-IFVFQRZ2.js} +5 -5
- package/dist/{chunk-6LBQL5US.js → chunk-JCLECECB.js} +2 -2
- package/dist/chunk-KVDUDYEN.js +1164 -0
- package/dist/chunk-KVDUDYEN.js.map +1 -0
- package/dist/{chunk-S5W37FPX.js → chunk-LEG7XWS2.js} +2 -2
- package/dist/chunk-M7XQSUBB.js +280 -0
- package/dist/chunk-M7XQSUBB.js.map +1 -0
- package/dist/{chunk-MQ24KOOR.js → chunk-PUEAEQSN.js} +2 -2
- package/dist/{chunk-RSKUUEBA.js → chunk-QYGIQ5NM.js} +140 -417
- package/dist/chunk-QYGIQ5NM.js.map +1 -0
- package/dist/{chunk-UE57H4MA.js → chunk-UXFOGILU.js} +2 -2
- package/dist/{chunk-OQMR2SDZ.js → chunk-VTR3MNYF.js} +2 -2
- package/dist/{chunk-4QEUKASL.js → chunk-W25I7G6U.js} +2 -2
- package/dist/{chunk-YJOWWRRS.js → chunk-WLZBVYC6.js} +125 -1206
- package/dist/chunk-WLZBVYC6.js.map +1 -0
- package/dist/{chunk-OOFBE62K.js → chunk-X7EJF46S.js} +2 -2
- package/dist/{chunk-BL33LBTN.js → chunk-XG4NAWAV.js} +3 -3
- package/dist/{chunk-ZZSXUZF3.js → chunk-YROCXMCK.js} +2 -2
- package/dist/{cli-B_6EMiQc.d.ts → cli-CuVEQWKr.d.ts} +3 -3
- package/dist/cli.d.ts +5 -5
- package/dist/cli.js +18 -17
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +3 -2
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +3 -2
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +3 -2
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/contradiction/index.d.ts +1 -1
- package/dist/contradiction/index.js +4 -4
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +3 -2
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +3 -3
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +8 -8
- package/dist/index.js +49 -45
- package/dist/index.js.map +1 -1
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +3 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -2
- package/dist/maintenance/rebuild-memory-projection.js +4 -3
- package/dist/mcp-memory-inspector-app.d.ts +4 -4
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +1 -1
- package/dist/namespaces/migrate.js +4 -3
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/storage.d.ts +1 -1
- package/dist/namespaces/storage.js +3 -2
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +7 -6
- package/dist/{orchestrator-Dlw3ae4B.d.ts → orchestrator-CoqytbK_.d.ts} +3 -2
- package/dist/orchestrator.d.ts +3 -3
- package/dist/orchestrator.js +12 -10
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +2 -2
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/schemas.d.ts +22 -22
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/index.d.ts +1 -1
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-C4sefXEI.d.ts → semantic-consolidation-BPs6BURk.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +4 -3
- package/dist/semantic-rule-promotion.js +3 -2
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +3 -2
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +1 -1
- package/dist/storage.js +2 -1
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/types.d.ts +12 -12
- package/dist/{types-2vqxmO0j.d.ts → types-CpMPD8xl.d.ts} +20 -1
- package/dist/types.d.ts +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +3 -2
- package/package.json +1 -1
- package/src/orchestrator.ts +58 -0
- package/src/wearables/auto-sync.test.ts +181 -0
- package/src/wearables/auto-sync.ts +129 -0
- package/src/wearables/config.test.ts +58 -8
- package/src/wearables/config.ts +75 -5
- package/src/wearables/pipeline.test.ts +87 -4
- package/src/wearables/pipeline.ts +43 -13
- package/src/wearables/types.ts +20 -1
- package/dist/chunk-RSKUUEBA.js.map +0 -1
- package/dist/chunk-YJOWWRRS.js.map +0 -1
- /package/dist/{chunk-BWK5EEKS.js.map → chunk-242XFZ36.js.map} +0 -0
- /package/dist/{chunk-K3BTOW7N.js.map → chunk-32U3N7H5.js.map} +0 -0
- /package/dist/{chunk-5S6IREG3.js.map → chunk-3RDYU3JS.js.map} +0 -0
- /package/dist/{chunk-SACS6KE6.js.map → chunk-4S3N6HFG.js.map} +0 -0
- /package/dist/{chunk-VUTPRX7K.js.map → chunk-5PT5I6JQ.js.map} +0 -0
- /package/dist/{chunk-2VJ7AJFX.js.map → chunk-7A2QKUUA.js.map} +0 -0
- /package/dist/{chunk-NRQJBK36.js.map → chunk-C4KKM62E.js.map} +0 -0
- /package/dist/{chunk-GXWFZYSR.js.map → chunk-CMN5AWAZ.js.map} +0 -0
- /package/dist/{chunk-F6USGHMO.js.map → chunk-DOBJH4I6.js.map} +0 -0
- /package/dist/{chunk-ADOD7PJC.js.map → chunk-IFVFQRZ2.js.map} +0 -0
- /package/dist/{chunk-6LBQL5US.js.map → chunk-JCLECECB.js.map} +0 -0
- /package/dist/{chunk-S5W37FPX.js.map → chunk-LEG7XWS2.js.map} +0 -0
- /package/dist/{chunk-MQ24KOOR.js.map → chunk-PUEAEQSN.js.map} +0 -0
- /package/dist/{chunk-UE57H4MA.js.map → chunk-UXFOGILU.js.map} +0 -0
- /package/dist/{chunk-OQMR2SDZ.js.map → chunk-VTR3MNYF.js.map} +0 -0
- /package/dist/{chunk-4QEUKASL.js.map → chunk-W25I7G6U.js.map} +0 -0
- /package/dist/{chunk-OOFBE62K.js.map → chunk-X7EJF46S.js.map} +0 -0
- /package/dist/{chunk-BL33LBTN.js.map → chunk-XG4NAWAV.js.map} +0 -0
- /package/dist/{chunk-ZZSXUZF3.js.map → chunk-YROCXMCK.js.map} +0 -0
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WEARABLE_SOURCE_PREFIX,
|
|
3
|
+
defaultTimezone,
|
|
4
|
+
loadSyncState,
|
|
5
|
+
syncWearableSource,
|
|
6
|
+
wearableSourceLabel
|
|
7
|
+
} from "./chunk-KVDUDYEN.js";
|
|
1
8
|
import {
|
|
2
9
|
migrateFromEngram
|
|
3
10
|
} from "./chunk-4HFJQCJZ.js";
|
|
@@ -22,7 +29,7 @@ import {
|
|
|
22
29
|
import {
|
|
23
30
|
CompoundingEngine,
|
|
24
31
|
defaultTierMigrationCycleBudget
|
|
25
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-UXFOGILU.js";
|
|
26
33
|
import {
|
|
27
34
|
SharedContextManager
|
|
28
35
|
} from "./chunk-DRD2Q7HQ.js";
|
|
@@ -168,7 +175,7 @@ import {
|
|
|
168
175
|
buildEntityRecallSection,
|
|
169
176
|
entityRecentTranscriptLookbackHours,
|
|
170
177
|
readRecentEntityTranscriptEntries
|
|
171
|
-
} from "./chunk-
|
|
178
|
+
} from "./chunk-JCLECECB.js";
|
|
172
179
|
import {
|
|
173
180
|
buildEventOrderRecallSection,
|
|
174
181
|
shouldRecallEventOrderEvidence
|
|
@@ -203,7 +210,7 @@ import {
|
|
|
203
210
|
materializeAfterSemanticConsolidation,
|
|
204
211
|
parseConsolidationResponse,
|
|
205
212
|
parseOperatorAwareConsolidationResponse
|
|
206
|
-
} from "./chunk-
|
|
213
|
+
} from "./chunk-X7EJF46S.js";
|
|
207
214
|
import {
|
|
208
215
|
normalizeReplaySessionKey
|
|
209
216
|
} from "./chunk-2PRQG7PV.js";
|
|
@@ -212,13 +219,13 @@ import {
|
|
|
212
219
|
} from "./chunk-X6IRLNOO.js";
|
|
213
220
|
import {
|
|
214
221
|
searchVerifiedEpisodes
|
|
215
|
-
} from "./chunk-
|
|
222
|
+
} from "./chunk-YROCXMCK.js";
|
|
216
223
|
import {
|
|
217
224
|
ThreadingManager
|
|
218
225
|
} from "./chunk-W4RVMTHR.js";
|
|
219
226
|
import {
|
|
220
227
|
searchVerifiedSemanticRules
|
|
221
|
-
} from "./chunk-
|
|
228
|
+
} from "./chunk-4S3N6HFG.js";
|
|
222
229
|
import {
|
|
223
230
|
searchWorkProductLedgerEntries
|
|
224
231
|
} from "./chunk-ZRWB5D4H.js";
|
|
@@ -237,7 +244,7 @@ import {
|
|
|
237
244
|
} from "./chunk-CYEPCZN5.js";
|
|
238
245
|
import {
|
|
239
246
|
NamespaceStorageRouter
|
|
240
|
-
} from "./chunk-
|
|
247
|
+
} from "./chunk-LEG7XWS2.js";
|
|
241
248
|
import {
|
|
242
249
|
namespaceIdentityFromToken
|
|
243
250
|
} from "./chunk-ZFXCQPNO.js";
|
|
@@ -286,14 +293,9 @@ import {
|
|
|
286
293
|
fallbackLlmRuntimeContextFromConfig
|
|
287
294
|
} from "./chunk-723OMPUI.js";
|
|
288
295
|
import {
|
|
289
|
-
applyCorrections,
|
|
290
|
-
applyOffTheRecord,
|
|
291
296
|
compileCorrectionRule,
|
|
292
|
-
compileCorrectionRules,
|
|
293
|
-
compileRedactionPatterns,
|
|
294
297
|
correctionsFilePath,
|
|
295
298
|
loadCorrectionsFile,
|
|
296
|
-
redactText,
|
|
297
299
|
saveCorrectionsFile
|
|
298
300
|
} from "./chunk-NDAH7BJ5.js";
|
|
299
301
|
import {
|
|
@@ -351,27 +353,24 @@ import {
|
|
|
351
353
|
} from "./chunk-XL7FK7PJ.js";
|
|
352
354
|
import {
|
|
353
355
|
buildChainFollowupGenerator
|
|
354
|
-
} from "./chunk-
|
|
356
|
+
} from "./chunk-CMN5AWAZ.js";
|
|
355
357
|
import {
|
|
356
358
|
ContentHashIndex,
|
|
357
359
|
StorageManager,
|
|
358
360
|
compareEntityTimestamps,
|
|
359
|
-
composeDayTranscriptBody,
|
|
360
|
-
composeDayTranscriptMeta,
|
|
361
361
|
fingerprintEntityStructuredFacts,
|
|
362
|
-
hashTranscriptBody,
|
|
363
|
-
isValidTranscriptDate,
|
|
364
|
-
loadSpeakerRegistry,
|
|
365
362
|
normalizeAttributePairs,
|
|
366
363
|
normalizeEntityName,
|
|
367
|
-
parseDayTranscript,
|
|
368
364
|
parseEntityFile,
|
|
369
|
-
resolveSpeaker,
|
|
370
|
-
saveSpeakerRegistry,
|
|
371
|
-
serializeDayTranscript,
|
|
372
|
-
speakerRegistryKey,
|
|
373
365
|
stripAttributesSuffix
|
|
374
|
-
} from "./chunk-
|
|
366
|
+
} from "./chunk-QYGIQ5NM.js";
|
|
367
|
+
import {
|
|
368
|
+
isValidTranscriptDate,
|
|
369
|
+
loadSpeakerRegistry,
|
|
370
|
+
parseDayTranscript,
|
|
371
|
+
saveSpeakerRegistry,
|
|
372
|
+
speakerRegistryKey
|
|
373
|
+
} from "./chunk-M7XQSUBB.js";
|
|
375
374
|
import {
|
|
376
375
|
attachCitation,
|
|
377
376
|
hasCitationForTemplate,
|
|
@@ -410,10 +409,6 @@ import {
|
|
|
410
409
|
decideLifecycleTransition,
|
|
411
410
|
resolveLifecycleState
|
|
412
411
|
} from "./chunk-TBBDFYXW.js";
|
|
413
|
-
import {
|
|
414
|
-
countRecallTokenOverlap,
|
|
415
|
-
normalizeRecallTokens
|
|
416
|
-
} from "./chunk-ZBJMUXZH.js";
|
|
417
412
|
import {
|
|
418
413
|
log
|
|
419
414
|
} from "./chunk-2ODBA7MQ.js";
|
|
@@ -429,7 +424,7 @@ import {
|
|
|
429
424
|
} from "./chunk-AC5LO7IU.js";
|
|
430
425
|
|
|
431
426
|
// src/orchestrator.ts
|
|
432
|
-
import
|
|
427
|
+
import path2 from "path";
|
|
433
428
|
import os from "os";
|
|
434
429
|
import { createHash, randomBytes } from "crypto";
|
|
435
430
|
import { existsSync } from "fs";
|
|
@@ -971,1096 +966,6 @@ function getTaxonomyFilePath(memoryDir) {
|
|
|
971
966
|
return path.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
|
|
972
967
|
}
|
|
973
968
|
|
|
974
|
-
// src/wearables/trust.ts
|
|
975
|
-
var TRUST_JUDGE_ACCEPT_BOOST = 0.15;
|
|
976
|
-
var TRUST_CROSS_SOURCE_BOOST = 0.15;
|
|
977
|
-
var TRUST_SUPPORTING_MEMORY_BOOST = 0.1;
|
|
978
|
-
var MIN_FACT_TOKENS = 4;
|
|
979
|
-
var CROSS_SOURCE_COVERAGE = 0.6;
|
|
980
|
-
var MEMORY_SUPPORT_COVERAGE = 0.7;
|
|
981
|
-
var MAX_MEMORIES_SCANNED = 5e3;
|
|
982
|
-
function computeTrustScore(input) {
|
|
983
|
-
const confidence = typeof input.extractionConfidence === "number" && Number.isFinite(input.extractionConfidence) ? Math.min(1, Math.max(0, input.extractionConfidence)) : 0.7;
|
|
984
|
-
let trust = confidence * Math.min(1, Math.max(0, input.sourceTrust));
|
|
985
|
-
if (input.judgeVerdict === "accept") trust += TRUST_JUDGE_ACCEPT_BOOST;
|
|
986
|
-
if (input.evidence.corroboratedBySources.length > 0) {
|
|
987
|
-
trust += TRUST_CROSS_SOURCE_BOOST;
|
|
988
|
-
}
|
|
989
|
-
if (input.evidence.supportingMemoryId !== void 0) {
|
|
990
|
-
trust += TRUST_SUPPORTING_MEMORY_BOOST;
|
|
991
|
-
}
|
|
992
|
-
return Math.min(1, Math.max(0, trust));
|
|
993
|
-
}
|
|
994
|
-
function tokenizeDayBody(body) {
|
|
995
|
-
return new Set(normalizeRecallTokens(body));
|
|
996
|
-
}
|
|
997
|
-
function findCorroboration(factText, context) {
|
|
998
|
-
const factTokens = normalizeRecallTokens(factText);
|
|
999
|
-
const evidence = { corroboratedBySources: [] };
|
|
1000
|
-
if (factTokens.length < MIN_FACT_TOKENS) return evidence;
|
|
1001
|
-
const factTokenSet = new Set(factTokens);
|
|
1002
|
-
for (const [sourceId, dayTokens] of context.otherSourceDayTokens) {
|
|
1003
|
-
let matches = 0;
|
|
1004
|
-
for (const token of factTokenSet) {
|
|
1005
|
-
if (dayTokens.has(token)) matches += 1;
|
|
1006
|
-
}
|
|
1007
|
-
if (matches / factTokenSet.size >= CROSS_SOURCE_COVERAGE) {
|
|
1008
|
-
evidence.corroboratedBySources.push(sourceId);
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
evidence.corroboratedBySources.sort();
|
|
1012
|
-
let scanned = 0;
|
|
1013
|
-
for (const memory of context.existingMemories) {
|
|
1014
|
-
if (scanned >= MAX_MEMORIES_SCANNED) break;
|
|
1015
|
-
scanned += 1;
|
|
1016
|
-
const matches = countRecallTokenOverlap(factTokenSet, memory.content);
|
|
1017
|
-
if (matches / factTokenSet.size >= MEMORY_SUPPORT_COVERAGE) {
|
|
1018
|
-
evidence.supportingMemoryId = memory.id;
|
|
1019
|
-
break;
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
return evidence;
|
|
1023
|
-
}
|
|
1024
|
-
function decideSmart(trust, judgeVerdict, thresholds) {
|
|
1025
|
-
if (judgeVerdict === "reject") {
|
|
1026
|
-
return { outcome: "drop", reason: "judge-rejected", trust };
|
|
1027
|
-
}
|
|
1028
|
-
if (judgeVerdict === "defer") {
|
|
1029
|
-
return { outcome: "review", reason: "judge-deferred", trust };
|
|
1030
|
-
}
|
|
1031
|
-
if (trust >= thresholds.autoApproveTrust) {
|
|
1032
|
-
return { outcome: "active", reason: "auto-approved", trust };
|
|
1033
|
-
}
|
|
1034
|
-
if (trust >= thresholds.reviewTrust) {
|
|
1035
|
-
return { outcome: "review", reason: "queued-for-review", trust };
|
|
1036
|
-
}
|
|
1037
|
-
return { outcome: "drop", reason: "below-trust", trust };
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
// src/wearables/memory-gen.ts
|
|
1041
|
-
function memoryStatusForMode(mode) {
|
|
1042
|
-
return mode === "auto" || mode === "smart" ? "active" : "pending_review";
|
|
1043
|
-
}
|
|
1044
|
-
var WEARABLE_SOURCE_PREFIX = "wearable";
|
|
1045
|
-
function wearableSourceLabel(sourceId) {
|
|
1046
|
-
return `${WEARABLE_SOURCE_PREFIX}:${sourceId}`;
|
|
1047
|
-
}
|
|
1048
|
-
function wearableDayTag(date) {
|
|
1049
|
-
return `wearable-day:${date}`;
|
|
1050
|
-
}
|
|
1051
|
-
var IMPORTANCE_RANK = {
|
|
1052
|
-
trivial: 0,
|
|
1053
|
-
low: 1,
|
|
1054
|
-
normal: 2,
|
|
1055
|
-
high: 3,
|
|
1056
|
-
critical: 4
|
|
1057
|
-
};
|
|
1058
|
-
var MAX_EXTRACTION_CHUNK_CHARS = 6e3;
|
|
1059
|
-
var MIN_CONVERSATION_CHARS = 80;
|
|
1060
|
-
function buildExtractionTurns(sourceId, date, conversation, registry) {
|
|
1061
|
-
const headerParts = [
|
|
1062
|
-
`Wearable transcript (${sourceId}) \u2014 ${date}`,
|
|
1063
|
-
conversation.title ? `"${conversation.title}"` : void 0,
|
|
1064
|
-
conversation.location ? `at ${conversation.location}` : void 0
|
|
1065
|
-
].filter((part) => typeof part === "string");
|
|
1066
|
-
const header = `[${headerParts.join(" \u2014 ")}]`;
|
|
1067
|
-
const lines = [];
|
|
1068
|
-
for (const segment of conversation.segments) {
|
|
1069
|
-
const { label } = resolveSpeaker(sourceId, segment, registry);
|
|
1070
|
-
lines.push(`${label}: ${segment.text}`);
|
|
1071
|
-
}
|
|
1072
|
-
const transcript = lines.join("\n");
|
|
1073
|
-
if (transcript.trim().length < MIN_CONVERSATION_CHARS) return [];
|
|
1074
|
-
const sessionKey = `wearables:${sourceId}:${date}:${conversation.id}`;
|
|
1075
|
-
const timestamp = conversation.startIso;
|
|
1076
|
-
const turns = [];
|
|
1077
|
-
let chunkLines = [];
|
|
1078
|
-
let chunkChars = 0;
|
|
1079
|
-
const flush = () => {
|
|
1080
|
-
if (chunkLines.length === 0) return;
|
|
1081
|
-
turns.push({
|
|
1082
|
-
role: "user",
|
|
1083
|
-
content: `${header}
|
|
1084
|
-
${chunkLines.join("\n")}`,
|
|
1085
|
-
timestamp,
|
|
1086
|
-
sourceValidAt: timestamp,
|
|
1087
|
-
sessionKey
|
|
1088
|
-
});
|
|
1089
|
-
chunkLines = [];
|
|
1090
|
-
chunkChars = 0;
|
|
1091
|
-
};
|
|
1092
|
-
for (const line of transcript.split("\n")) {
|
|
1093
|
-
if (chunkChars + line.length + 1 > MAX_EXTRACTION_CHUNK_CHARS) flush();
|
|
1094
|
-
chunkLines.push(line);
|
|
1095
|
-
chunkChars += line.length + 1;
|
|
1096
|
-
}
|
|
1097
|
-
flush();
|
|
1098
|
-
return turns;
|
|
1099
|
-
}
|
|
1100
|
-
async function scoreCandidates(novel, settings, deps, result) {
|
|
1101
|
-
const scored = /* @__PURE__ */ new Map();
|
|
1102
|
-
if (novel.length === 0) return scored;
|
|
1103
|
-
let verdicts;
|
|
1104
|
-
if (deps.judgeFacts) {
|
|
1105
|
-
const judgeCandidates = novel.map((candidate) => ({
|
|
1106
|
-
text: candidate.fact.content,
|
|
1107
|
-
category: candidate.fact.category,
|
|
1108
|
-
confidence: typeof candidate.fact.confidence === "number" ? candidate.fact.confidence : 0.7,
|
|
1109
|
-
tags: candidate.fact.tags ?? [],
|
|
1110
|
-
importanceLevel: candidate.importance.level
|
|
1111
|
-
}));
|
|
1112
|
-
try {
|
|
1113
|
-
const judgeResult = await deps.judgeFacts(judgeCandidates);
|
|
1114
|
-
verdicts = /* @__PURE__ */ new Map();
|
|
1115
|
-
for (const [index, verdict] of judgeResult.verdicts) {
|
|
1116
|
-
verdicts.set(index, getVerdictKind(verdict));
|
|
1117
|
-
}
|
|
1118
|
-
} catch (err) {
|
|
1119
|
-
result.warnings.push(
|
|
1120
|
-
`extraction judge unavailable for this pass: ${describeErrorForOperator(err)} \u2014 trust scoring continued without judge verdicts`
|
|
1121
|
-
);
|
|
1122
|
-
}
|
|
1123
|
-
}
|
|
1124
|
-
const corroboration = deps.corroboration ?? {
|
|
1125
|
-
otherSourceDayTokens: /* @__PURE__ */ new Map(),
|
|
1126
|
-
existingMemories: []
|
|
1127
|
-
};
|
|
1128
|
-
novel.forEach((candidate, index) => {
|
|
1129
|
-
const evidence = findCorroboration(candidate.fact.content, corroboration);
|
|
1130
|
-
const verdict = verdicts?.get(index);
|
|
1131
|
-
const trust = computeTrustScore({
|
|
1132
|
-
extractionConfidence: candidate.fact.confidence,
|
|
1133
|
-
sourceTrust: settings.sourceTrust,
|
|
1134
|
-
judgeVerdict: verdict,
|
|
1135
|
-
evidence
|
|
1136
|
-
});
|
|
1137
|
-
scored.set(index, { trust, ...verdict !== void 0 ? { verdict } : {}, evidence });
|
|
1138
|
-
});
|
|
1139
|
-
return scored;
|
|
1140
|
-
}
|
|
1141
|
-
async function generateWearableMemories(sourceId, date, conversations, settings, registry, deps) {
|
|
1142
|
-
const result = {
|
|
1143
|
-
created: 0,
|
|
1144
|
-
promoted: 0,
|
|
1145
|
-
demoted: 0,
|
|
1146
|
-
skipped: 0,
|
|
1147
|
-
skippedByReason: {},
|
|
1148
|
-
warnings: [],
|
|
1149
|
-
completed: true
|
|
1150
|
-
};
|
|
1151
|
-
if (settings.memoryMode === "off") return result;
|
|
1152
|
-
const skip = (reason, count = 1) => {
|
|
1153
|
-
result.skipped += count;
|
|
1154
|
-
result.skippedByReason[reason] = (result.skippedByReason[reason] ?? 0) + count;
|
|
1155
|
-
};
|
|
1156
|
-
const candidates = [];
|
|
1157
|
-
const seenContent = /* @__PURE__ */ new Set();
|
|
1158
|
-
for (const conversation of conversations) {
|
|
1159
|
-
const turns = buildExtractionTurns(sourceId, date, conversation, registry);
|
|
1160
|
-
if (turns.length === 0) continue;
|
|
1161
|
-
let extraction;
|
|
1162
|
-
try {
|
|
1163
|
-
extraction = await deps.extract(turns);
|
|
1164
|
-
} catch (err) {
|
|
1165
|
-
result.warnings.push(
|
|
1166
|
-
`extraction failed for ${sourceId}/${date} (conversation ${conversation.id}): ${describeErrorForOperator(err)} \u2014 the memory pass for this day retries on the next sync`
|
|
1167
|
-
);
|
|
1168
|
-
result.completed = false;
|
|
1169
|
-
break;
|
|
1170
|
-
}
|
|
1171
|
-
for (const fact of extraction.facts) {
|
|
1172
|
-
const content = fact.content?.trim();
|
|
1173
|
-
if (!content) {
|
|
1174
|
-
skip("empty");
|
|
1175
|
-
continue;
|
|
1176
|
-
}
|
|
1177
|
-
if (fact.category === "procedure" || fact.category === "reasoning_trace") {
|
|
1178
|
-
skip("unsupported-category");
|
|
1179
|
-
continue;
|
|
1180
|
-
}
|
|
1181
|
-
if (settings.memoryMode !== "smart" && typeof fact.confidence === "number" && fact.confidence < settings.minConfidence) {
|
|
1182
|
-
skip("below-confidence");
|
|
1183
|
-
continue;
|
|
1184
|
-
}
|
|
1185
|
-
const importance = scoreImportance(content, fact.category, fact.tags ?? []);
|
|
1186
|
-
if (IMPORTANCE_RANK[importance.level] < IMPORTANCE_RANK[settings.minImportance]) {
|
|
1187
|
-
skip("below-importance");
|
|
1188
|
-
continue;
|
|
1189
|
-
}
|
|
1190
|
-
const dedupKey = content.toLowerCase();
|
|
1191
|
-
if (seenContent.has(dedupKey)) {
|
|
1192
|
-
skip("duplicate-in-run");
|
|
1193
|
-
continue;
|
|
1194
|
-
}
|
|
1195
|
-
seenContent.add(dedupKey);
|
|
1196
|
-
candidates.push({ fact: { ...fact, content }, importance, conversation });
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
const novel = [];
|
|
1200
|
-
const promotable = [];
|
|
1201
|
-
for (const candidate of candidates) {
|
|
1202
|
-
if (await deps.writer.hasFactContentHash(candidate.fact.content)) {
|
|
1203
|
-
if (settings.memoryMode === "smart" && deps.writer.findWearableMemoryByContent !== void 0 && deps.writer.promoteWearableMemory !== void 0) {
|
|
1204
|
-
promotable.push(candidate);
|
|
1205
|
-
} else {
|
|
1206
|
-
skip("duplicate-existing");
|
|
1207
|
-
}
|
|
1208
|
-
continue;
|
|
1209
|
-
}
|
|
1210
|
-
novel.push(candidate);
|
|
1211
|
-
}
|
|
1212
|
-
if (promotable.length > 0) {
|
|
1213
|
-
const promoteScores = await scoreCandidates(promotable, settings, deps, result);
|
|
1214
|
-
for (const [index, candidate] of promotable.entries()) {
|
|
1215
|
-
const scored = promoteScores.get(index);
|
|
1216
|
-
const decision = scored ? decideSmart(scored.trust, scored.verdict, settings) : void 0;
|
|
1217
|
-
if (!scored || !decision) {
|
|
1218
|
-
skip("duplicate-existing");
|
|
1219
|
-
continue;
|
|
1220
|
-
}
|
|
1221
|
-
if (scored.verdict === "reject") {
|
|
1222
|
-
if (deps.writer.demoteWearableMemory !== void 0) {
|
|
1223
|
-
const existingForDemote = await deps.writer.findWearableMemoryByContent(
|
|
1224
|
-
candidate.fact.content
|
|
1225
|
-
);
|
|
1226
|
-
if (existingForDemote && existingForDemote.status === "pending_review" && await deps.writer.demoteWearableMemory(existingForDemote.id, {
|
|
1227
|
-
trustScore: scored.trust.toFixed(3),
|
|
1228
|
-
trustDecision: "demoted-by-rejection",
|
|
1229
|
-
judgeVerdict: "reject"
|
|
1230
|
-
})) {
|
|
1231
|
-
result.demoted += 1;
|
|
1232
|
-
continue;
|
|
1233
|
-
}
|
|
1234
|
-
}
|
|
1235
|
-
skip("duplicate-existing");
|
|
1236
|
-
continue;
|
|
1237
|
-
}
|
|
1238
|
-
if (decision.outcome !== "active") {
|
|
1239
|
-
skip("duplicate-existing");
|
|
1240
|
-
continue;
|
|
1241
|
-
}
|
|
1242
|
-
const existing = await deps.writer.findWearableMemoryByContent(
|
|
1243
|
-
candidate.fact.content
|
|
1244
|
-
);
|
|
1245
|
-
if (!existing || existing.status !== "pending_review") {
|
|
1246
|
-
skip("duplicate-existing");
|
|
1247
|
-
continue;
|
|
1248
|
-
}
|
|
1249
|
-
const promoted = await deps.writer.promoteWearableMemory(
|
|
1250
|
-
existing.id,
|
|
1251
|
-
{
|
|
1252
|
-
trustScore: scored.trust.toFixed(3),
|
|
1253
|
-
trustDecision: "promoted-by-corroboration",
|
|
1254
|
-
...scored.verdict !== void 0 ? { judgeVerdict: scored.verdict } : {},
|
|
1255
|
-
...scored.evidence.corroboratedBySources.length > 0 ? { corroboratedBySources: scored.evidence.corroboratedBySources.join(",") } : {},
|
|
1256
|
-
...scored.evidence.supportingMemoryId !== void 0 ? { supportingMemoryId: scored.evidence.supportingMemoryId } : {}
|
|
1257
|
-
},
|
|
1258
|
-
scored.trust
|
|
1259
|
-
);
|
|
1260
|
-
if (promoted) {
|
|
1261
|
-
result.promoted += 1;
|
|
1262
|
-
} else {
|
|
1263
|
-
skip("duplicate-existing");
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
let trustById = /* @__PURE__ */ new Map();
|
|
1268
|
-
if (settings.memoryMode === "smart") {
|
|
1269
|
-
trustById = await scoreCandidates(novel, settings, deps, result);
|
|
1270
|
-
}
|
|
1271
|
-
const modeStatus = memoryStatusForMode(settings.memoryMode);
|
|
1272
|
-
const writable = [];
|
|
1273
|
-
novel.forEach((candidate, index) => {
|
|
1274
|
-
if (settings.memoryMode !== "smart") {
|
|
1275
|
-
writable.push({ candidate, index, status: modeStatus, trustAttributes: {} });
|
|
1276
|
-
return;
|
|
1277
|
-
}
|
|
1278
|
-
const scored = trustById.get(index);
|
|
1279
|
-
if (!scored) return;
|
|
1280
|
-
const decision = decideSmart(scored.trust, scored.verdict, settings);
|
|
1281
|
-
if (decision.outcome === "drop") {
|
|
1282
|
-
skip(decision.reason);
|
|
1283
|
-
return;
|
|
1284
|
-
}
|
|
1285
|
-
writable.push({
|
|
1286
|
-
candidate,
|
|
1287
|
-
index,
|
|
1288
|
-
status: decision.outcome === "active" ? "active" : "pending_review",
|
|
1289
|
-
trustAttributes: {
|
|
1290
|
-
trustScore: scored.trust.toFixed(3),
|
|
1291
|
-
trustDecision: decision.reason,
|
|
1292
|
-
...scored.verdict !== void 0 ? { judgeVerdict: scored.verdict } : {},
|
|
1293
|
-
...scored.evidence.corroboratedBySources.length > 0 ? { corroboratedBySources: scored.evidence.corroboratedBySources.join(",") } : {},
|
|
1294
|
-
...scored.evidence.supportingMemoryId !== void 0 ? { supportingMemoryId: scored.evidence.supportingMemoryId } : {}
|
|
1295
|
-
}
|
|
1296
|
-
});
|
|
1297
|
-
});
|
|
1298
|
-
const strength = (entry) => settings.memoryMode === "smart" ? trustById.get(entry.index)?.trust ?? 0 : entry.candidate.importance.score;
|
|
1299
|
-
writable.sort((a, b) => {
|
|
1300
|
-
const sa = strength(a);
|
|
1301
|
-
const sb = strength(b);
|
|
1302
|
-
if (sa > sb) return -1;
|
|
1303
|
-
if (sa < sb) return 1;
|
|
1304
|
-
if (a.candidate.fact.content < b.candidate.fact.content) return -1;
|
|
1305
|
-
if (a.candidate.fact.content > b.candidate.fact.content) return 1;
|
|
1306
|
-
return 0;
|
|
1307
|
-
});
|
|
1308
|
-
const cap = settings.maxMemoriesPerDay;
|
|
1309
|
-
const kept = cap > 0 ? writable.slice(0, cap) : writable;
|
|
1310
|
-
if (writable.length > kept.length) {
|
|
1311
|
-
skip("over-day-cap", writable.length - kept.length);
|
|
1312
|
-
}
|
|
1313
|
-
for (const { candidate, index, status, trustAttributes } of kept) {
|
|
1314
|
-
const tags = [
|
|
1315
|
-
.../* @__PURE__ */ new Set([
|
|
1316
|
-
...candidate.fact.tags ?? [],
|
|
1317
|
-
WEARABLE_SOURCE_PREFIX,
|
|
1318
|
-
wearableSourceLabel(sourceId),
|
|
1319
|
-
wearableDayTag(date)
|
|
1320
|
-
])
|
|
1321
|
-
];
|
|
1322
|
-
await deps.writer.writeMemory(candidate.fact.category, candidate.fact.content, {
|
|
1323
|
-
confidence: settings.memoryMode === "smart" ? trustById.get(index)?.trust : candidate.fact.confidence,
|
|
1324
|
-
tags,
|
|
1325
|
-
source: wearableSourceLabel(sourceId),
|
|
1326
|
-
importance: candidate.importance,
|
|
1327
|
-
validAt: candidate.conversation.startIso,
|
|
1328
|
-
structuredAttributes: {
|
|
1329
|
-
...candidate.fact.structuredAttributes ?? {},
|
|
1330
|
-
wearableSource: sourceId,
|
|
1331
|
-
wearableDate: date,
|
|
1332
|
-
wearableConversationId: candidate.conversation.id,
|
|
1333
|
-
...trustAttributes
|
|
1334
|
-
},
|
|
1335
|
-
contentHashSource: candidate.fact.content,
|
|
1336
|
-
status
|
|
1337
|
-
});
|
|
1338
|
-
result.created += 1;
|
|
1339
|
-
}
|
|
1340
|
-
return result;
|
|
1341
|
-
}
|
|
1342
|
-
async function writeDailyDigestMemory(sourceId, date, conversations, settings, registry, writer) {
|
|
1343
|
-
if (settings.memoryMode === "off") return false;
|
|
1344
|
-
if (conversations.length === 0) return false;
|
|
1345
|
-
const lines = conversations.map((conversation) => {
|
|
1346
|
-
const title = conversation.title?.trim() || "Untitled conversation";
|
|
1347
|
-
const speakers = new Set(
|
|
1348
|
-
conversation.segments.map(
|
|
1349
|
-
(segment) => resolveSpeaker(sourceId, segment, registry).label
|
|
1350
|
-
)
|
|
1351
|
-
);
|
|
1352
|
-
return `- ${title} (${speakers.size} speaker${speakers.size === 1 ? "" : "s"})`;
|
|
1353
|
-
});
|
|
1354
|
-
const content = `Wearable day digest \u2014 ${sourceId}, ${date}: ${conversations.length} recorded conversation${conversations.length === 1 ? "" : "s"}.
|
|
1355
|
-
` + lines.join("\n");
|
|
1356
|
-
if (await writer.hasFactContentHash(content)) return false;
|
|
1357
|
-
await writer.writeMemory("moment", content, {
|
|
1358
|
-
confidence: 0.9,
|
|
1359
|
-
tags: [
|
|
1360
|
-
WEARABLE_SOURCE_PREFIX,
|
|
1361
|
-
wearableSourceLabel(sourceId),
|
|
1362
|
-
wearableDayTag(date),
|
|
1363
|
-
"daily-digest"
|
|
1364
|
-
],
|
|
1365
|
-
source: wearableSourceLabel(sourceId),
|
|
1366
|
-
importance: scoreImportance(content, "moment", ["daily-digest"]),
|
|
1367
|
-
validAt: `${date}T00:00:00.000Z`,
|
|
1368
|
-
structuredAttributes: {
|
|
1369
|
-
wearableSource: sourceId,
|
|
1370
|
-
wearableDate: date
|
|
1371
|
-
},
|
|
1372
|
-
contentHashSource: content,
|
|
1373
|
-
status: memoryStatusForMode(settings.memoryMode),
|
|
1374
|
-
memoryKind: "episode"
|
|
1375
|
-
});
|
|
1376
|
-
return true;
|
|
1377
|
-
}
|
|
1378
|
-
var NATIVE_TRUST_FACTOR = 0.9;
|
|
1379
|
-
async function importNativeMemories(sourceId, memories, alreadyImportedIds, settings, deps) {
|
|
1380
|
-
let imported = 0;
|
|
1381
|
-
const importedIds = [];
|
|
1382
|
-
const warnings = [];
|
|
1383
|
-
const seenContent = /* @__PURE__ */ new Set();
|
|
1384
|
-
const smart = settings.importNativeMemories === "smart";
|
|
1385
|
-
const novel = [];
|
|
1386
|
-
for (const memory of memories) {
|
|
1387
|
-
const content = memory.content?.trim();
|
|
1388
|
-
if (!content) continue;
|
|
1389
|
-
if (alreadyImportedIds.has(memory.id)) continue;
|
|
1390
|
-
if (seenContent.has(content) || await deps.writer.hasFactContentHash(content)) {
|
|
1391
|
-
importedIds.push(memory.id);
|
|
1392
|
-
continue;
|
|
1393
|
-
}
|
|
1394
|
-
seenContent.add(content);
|
|
1395
|
-
novel.push({ ...memory, content });
|
|
1396
|
-
}
|
|
1397
|
-
let verdicts;
|
|
1398
|
-
if (smart && deps.judgeFacts && novel.length > 0) {
|
|
1399
|
-
try {
|
|
1400
|
-
const judgeResult = await deps.judgeFacts(
|
|
1401
|
-
novel.map((memory) => ({
|
|
1402
|
-
text: memory.content,
|
|
1403
|
-
category: "fact",
|
|
1404
|
-
confidence: 0.7,
|
|
1405
|
-
tags: memory.tags ?? []
|
|
1406
|
-
}))
|
|
1407
|
-
);
|
|
1408
|
-
verdicts = /* @__PURE__ */ new Map();
|
|
1409
|
-
for (const [index, verdict] of judgeResult.verdicts) {
|
|
1410
|
-
verdicts.set(index, getVerdictKind(verdict));
|
|
1411
|
-
}
|
|
1412
|
-
} catch (err) {
|
|
1413
|
-
warnings.push(
|
|
1414
|
-
`extraction judge unavailable for native import: ${describeErrorForOperator(err)} \u2014 trust scoring continued without judge verdicts`
|
|
1415
|
-
);
|
|
1416
|
-
}
|
|
1417
|
-
}
|
|
1418
|
-
const corroboration = deps.corroboration ?? {
|
|
1419
|
-
otherSourceDayTokens: /* @__PURE__ */ new Map(),
|
|
1420
|
-
existingMemories: []
|
|
1421
|
-
};
|
|
1422
|
-
for (const [index, memory] of novel.entries()) {
|
|
1423
|
-
const content = memory.content;
|
|
1424
|
-
let status = "pending_review";
|
|
1425
|
-
let trustAttributes = {};
|
|
1426
|
-
let confidence = 0.6;
|
|
1427
|
-
if (smart) {
|
|
1428
|
-
const evidence = findCorroboration(content, corroboration);
|
|
1429
|
-
const verdict = verdicts?.get(index);
|
|
1430
|
-
const trust = computeTrustScore({
|
|
1431
|
-
extractionConfidence: void 0,
|
|
1432
|
-
sourceTrust: settings.sourceTrust * NATIVE_TRUST_FACTOR,
|
|
1433
|
-
judgeVerdict: verdict,
|
|
1434
|
-
evidence
|
|
1435
|
-
});
|
|
1436
|
-
const decision = decideSmart(trust, verdict, settings);
|
|
1437
|
-
if (decision.outcome === "drop") {
|
|
1438
|
-
continue;
|
|
1439
|
-
}
|
|
1440
|
-
status = decision.outcome === "active" ? "active" : "pending_review";
|
|
1441
|
-
confidence = trust;
|
|
1442
|
-
trustAttributes = {
|
|
1443
|
-
trustScore: trust.toFixed(3),
|
|
1444
|
-
trustDecision: decision.reason,
|
|
1445
|
-
...verdict !== void 0 ? { judgeVerdict: verdict } : {},
|
|
1446
|
-
...evidence.corroboratedBySources.length > 0 ? { corroboratedBySources: evidence.corroboratedBySources.join(",") } : {},
|
|
1447
|
-
...evidence.supportingMemoryId !== void 0 ? { supportingMemoryId: evidence.supportingMemoryId } : {}
|
|
1448
|
-
};
|
|
1449
|
-
}
|
|
1450
|
-
await deps.writer.writeMemory("fact", content, {
|
|
1451
|
-
confidence,
|
|
1452
|
-
tags: [
|
|
1453
|
-
.../* @__PURE__ */ new Set([
|
|
1454
|
-
...memory.tags ?? [],
|
|
1455
|
-
WEARABLE_SOURCE_PREFIX,
|
|
1456
|
-
wearableSourceLabel(sourceId),
|
|
1457
|
-
"native-import"
|
|
1458
|
-
])
|
|
1459
|
-
],
|
|
1460
|
-
source: `${wearableSourceLabel(sourceId)}:native`,
|
|
1461
|
-
importance: scoreImportance(content, "fact", memory.tags ?? []),
|
|
1462
|
-
validAt: memory.createdIso,
|
|
1463
|
-
structuredAttributes: {
|
|
1464
|
-
wearableSource: sourceId,
|
|
1465
|
-
wearableNativeId: memory.id,
|
|
1466
|
-
...trustAttributes
|
|
1467
|
-
},
|
|
1468
|
-
contentHashSource: content,
|
|
1469
|
-
status
|
|
1470
|
-
});
|
|
1471
|
-
imported += 1;
|
|
1472
|
-
importedIds.push(memory.id);
|
|
1473
|
-
}
|
|
1474
|
-
return { imported, importedIds, warnings };
|
|
1475
|
-
}
|
|
1476
|
-
|
|
1477
|
-
// src/wearables/cleanup.ts
|
|
1478
|
-
var MERGE_GAP_MS = 3e4;
|
|
1479
|
-
var FILLER_TOKENS = ["um", "uh", "uhm", "umm", "uhh", "erm", "hmm", "mhm"];
|
|
1480
|
-
var FILLER_PATTERN = new RegExp(
|
|
1481
|
-
// Leading/trailing punctuation around the filler collapses with it so
|
|
1482
|
-
// "Um, so we should" -> "so we should" rather than ", so we should".
|
|
1483
|
-
`(?:^|\\s)(?:${FILLER_TOKENS.join("|")})[,.]?(?=\\s|$)`,
|
|
1484
|
-
"gi"
|
|
1485
|
-
);
|
|
1486
|
-
function cleanConversation(conversation, settings) {
|
|
1487
|
-
let segments = conversation.segments.map((segment) => ({ ...segment }));
|
|
1488
|
-
let droppedSegments = 0;
|
|
1489
|
-
let mergedSegments = 0;
|
|
1490
|
-
if (settings.stripFillers) {
|
|
1491
|
-
for (const segment of segments) {
|
|
1492
|
-
segment.text = stripFillerTokens(segment.text);
|
|
1493
|
-
}
|
|
1494
|
-
}
|
|
1495
|
-
if (settings.collapseRepeats) {
|
|
1496
|
-
for (const segment of segments) {
|
|
1497
|
-
segment.text = collapseImmediateRepeats(segment.text);
|
|
1498
|
-
}
|
|
1499
|
-
}
|
|
1500
|
-
for (const segment of segments) {
|
|
1501
|
-
segment.text = normalizeWhitespace(segment.text);
|
|
1502
|
-
}
|
|
1503
|
-
if (settings.dropLowQuality) {
|
|
1504
|
-
const kept = [];
|
|
1505
|
-
for (const segment of segments) {
|
|
1506
|
-
if (isLowQualitySegment(segment.text)) {
|
|
1507
|
-
droppedSegments += 1;
|
|
1508
|
-
} else {
|
|
1509
|
-
kept.push(segment);
|
|
1510
|
-
}
|
|
1511
|
-
}
|
|
1512
|
-
segments = kept;
|
|
1513
|
-
} else {
|
|
1514
|
-
const kept = segments.filter((segment) => segment.text.length > 0);
|
|
1515
|
-
droppedSegments += segments.length - kept.length;
|
|
1516
|
-
segments = kept;
|
|
1517
|
-
}
|
|
1518
|
-
if (settings.mergeSameSpeaker) {
|
|
1519
|
-
const merged = [];
|
|
1520
|
-
for (const segment of segments) {
|
|
1521
|
-
const previous = merged[merged.length - 1];
|
|
1522
|
-
if (previous && canMerge(previous, segment)) {
|
|
1523
|
-
previous.text = `${previous.text} ${segment.text}`.trim();
|
|
1524
|
-
if (segment.endIso) previous.endIso = segment.endIso;
|
|
1525
|
-
mergedSegments += 1;
|
|
1526
|
-
} else {
|
|
1527
|
-
merged.push(segment);
|
|
1528
|
-
}
|
|
1529
|
-
}
|
|
1530
|
-
segments = merged;
|
|
1531
|
-
}
|
|
1532
|
-
return {
|
|
1533
|
-
conversation: { ...conversation, segments },
|
|
1534
|
-
droppedSegments,
|
|
1535
|
-
mergedSegments
|
|
1536
|
-
};
|
|
1537
|
-
}
|
|
1538
|
-
function canMerge(previous, next) {
|
|
1539
|
-
if (previous.speakerKey !== next.speakerKey) return false;
|
|
1540
|
-
const previousEnd = previous.endIso ? Date.parse(previous.endIso) : NaN;
|
|
1541
|
-
const nextStart = next.startIso ? Date.parse(next.startIso) : NaN;
|
|
1542
|
-
if (Number.isNaN(previousEnd) || Number.isNaN(nextStart)) return true;
|
|
1543
|
-
return nextStart - previousEnd <= MERGE_GAP_MS;
|
|
1544
|
-
}
|
|
1545
|
-
function stripFillerTokens(text) {
|
|
1546
|
-
return normalizeWhitespace(text.replace(FILLER_PATTERN, " "));
|
|
1547
|
-
}
|
|
1548
|
-
function collapseImmediateRepeats(text) {
|
|
1549
|
-
const words = text.split(/\s+/).filter((word) => word.length > 0);
|
|
1550
|
-
if (words.length < 2) return text.trim();
|
|
1551
|
-
const out = [];
|
|
1552
|
-
let index = 0;
|
|
1553
|
-
while (index < words.length) {
|
|
1554
|
-
out.push(words[index]);
|
|
1555
|
-
index += 1;
|
|
1556
|
-
let matched = true;
|
|
1557
|
-
while (matched) {
|
|
1558
|
-
matched = false;
|
|
1559
|
-
for (let size = 4; size >= 1; size--) {
|
|
1560
|
-
if (out.length < size || index + size > words.length) continue;
|
|
1561
|
-
const tail = out.slice(-size).join(" ").toLowerCase();
|
|
1562
|
-
if (!/\p{L}/u.test(tail)) continue;
|
|
1563
|
-
const ahead = words.slice(index, index + size).join(" ").toLowerCase();
|
|
1564
|
-
if (tail === ahead) {
|
|
1565
|
-
index += size;
|
|
1566
|
-
matched = true;
|
|
1567
|
-
break;
|
|
1568
|
-
}
|
|
1569
|
-
}
|
|
1570
|
-
}
|
|
1571
|
-
}
|
|
1572
|
-
return out.join(" ");
|
|
1573
|
-
}
|
|
1574
|
-
function isLowQualitySegment(text) {
|
|
1575
|
-
const trimmed = text.trim();
|
|
1576
|
-
if (trimmed.length === 0) return true;
|
|
1577
|
-
if (/^(.)\1{4,}$/.test(trimmed)) return true;
|
|
1578
|
-
const letters = trimmed.replace(/[^\p{L}\p{N}]/gu, "");
|
|
1579
|
-
if (letters.length === 0) return true;
|
|
1580
|
-
if (trimmed.length >= 12 && letters.length / trimmed.length < 0.3) {
|
|
1581
|
-
return true;
|
|
1582
|
-
}
|
|
1583
|
-
const words = trimmed.toLowerCase().split(/\s+/);
|
|
1584
|
-
if (words.length >= 5) {
|
|
1585
|
-
const unique = new Set(words);
|
|
1586
|
-
if (unique.size === 1) return true;
|
|
1587
|
-
}
|
|
1588
|
-
return false;
|
|
1589
|
-
}
|
|
1590
|
-
function normalizeWhitespace(text) {
|
|
1591
|
-
return text.replace(/\s+/g, " ").trim();
|
|
1592
|
-
}
|
|
1593
|
-
|
|
1594
|
-
// src/wearables/sync-state.ts
|
|
1595
|
-
import { promises as fsPromises } from "fs";
|
|
1596
|
-
import * as path2 from "path";
|
|
1597
|
-
var MAX_TRACKED_NATIVE_IDS = 5e3;
|
|
1598
|
-
var MAX_TRACKED_DAY_HASHES = 800;
|
|
1599
|
-
function syncStateFilePath(memoryDir) {
|
|
1600
|
-
return path2.join(memoryDir, "state", "wearables", "sync.json");
|
|
1601
|
-
}
|
|
1602
|
-
function emptySyncState() {
|
|
1603
|
-
return { version: 1, sources: {} };
|
|
1604
|
-
}
|
|
1605
|
-
async function loadSyncState(memoryDir) {
|
|
1606
|
-
const filePath = syncStateFilePath(memoryDir);
|
|
1607
|
-
let raw;
|
|
1608
|
-
try {
|
|
1609
|
-
raw = await fsPromises.readFile(filePath, "utf-8");
|
|
1610
|
-
} catch (err) {
|
|
1611
|
-
if (err.code === "ENOENT") {
|
|
1612
|
-
return emptySyncState();
|
|
1613
|
-
}
|
|
1614
|
-
throw err;
|
|
1615
|
-
}
|
|
1616
|
-
let parsed;
|
|
1617
|
-
try {
|
|
1618
|
-
parsed = JSON.parse(raw);
|
|
1619
|
-
} catch {
|
|
1620
|
-
return emptySyncState();
|
|
1621
|
-
}
|
|
1622
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof parsed.sources !== "object" || parsed.sources === null) {
|
|
1623
|
-
return emptySyncState();
|
|
1624
|
-
}
|
|
1625
|
-
return { version: 1, sources: parsed.sources };
|
|
1626
|
-
}
|
|
1627
|
-
async function saveSyncState(memoryDir, state) {
|
|
1628
|
-
const filePath = syncStateFilePath(memoryDir);
|
|
1629
|
-
await fsPromises.mkdir(path2.dirname(filePath), { recursive: true });
|
|
1630
|
-
const tmpPath = `${filePath}.tmp-${process.pid}-${Date.now().toString(36)}`;
|
|
1631
|
-
await fsPromises.writeFile(
|
|
1632
|
-
tmpPath,
|
|
1633
|
-
`${JSON.stringify(state, null, 2)}
|
|
1634
|
-
`,
|
|
1635
|
-
"utf-8"
|
|
1636
|
-
);
|
|
1637
|
-
try {
|
|
1638
|
-
await fsPromises.rename(tmpPath, filePath);
|
|
1639
|
-
} catch (err) {
|
|
1640
|
-
await fsPromises.unlink(tmpPath).catch(() => void 0);
|
|
1641
|
-
throw err;
|
|
1642
|
-
}
|
|
1643
|
-
}
|
|
1644
|
-
function updateSourceSyncState(state, sourceId, update) {
|
|
1645
|
-
const previous = state.sources[sourceId];
|
|
1646
|
-
const mergedHashes = {
|
|
1647
|
-
...previous?.dayHashes ?? {},
|
|
1648
|
-
...update.dayHashes
|
|
1649
|
-
};
|
|
1650
|
-
const hashKeys = Object.keys(mergedHashes).sort();
|
|
1651
|
-
while (hashKeys.length > MAX_TRACKED_DAY_HASHES) {
|
|
1652
|
-
const oldest = hashKeys.shift();
|
|
1653
|
-
if (oldest === void 0) break;
|
|
1654
|
-
delete mergedHashes[oldest];
|
|
1655
|
-
}
|
|
1656
|
-
const mergedMemoryHashes = {
|
|
1657
|
-
...previous?.memoryDayHashes ?? {},
|
|
1658
|
-
...update.memoryDayHashes ?? {}
|
|
1659
|
-
};
|
|
1660
|
-
for (const day of update.clearMemoryDays ?? []) {
|
|
1661
|
-
if (!(day in (update.memoryDayHashes ?? {}))) {
|
|
1662
|
-
delete mergedMemoryHashes[day];
|
|
1663
|
-
}
|
|
1664
|
-
}
|
|
1665
|
-
const memoryHashKeys = Object.keys(mergedMemoryHashes).sort();
|
|
1666
|
-
while (memoryHashKeys.length > MAX_TRACKED_DAY_HASHES) {
|
|
1667
|
-
const oldest = memoryHashKeys.shift();
|
|
1668
|
-
if (oldest === void 0) break;
|
|
1669
|
-
delete mergedMemoryHashes[oldest];
|
|
1670
|
-
}
|
|
1671
|
-
const mergedNativeIds = [
|
|
1672
|
-
...previous?.importedNativeMemoryIds ?? [],
|
|
1673
|
-
...update.importedNativeMemoryIds ?? []
|
|
1674
|
-
];
|
|
1675
|
-
const dedupedNativeIds = [...new Set(mergedNativeIds)];
|
|
1676
|
-
const boundedNativeIds = dedupedNativeIds.length > MAX_TRACKED_NATIVE_IDS ? dedupedNativeIds.slice(dedupedNativeIds.length - MAX_TRACKED_NATIVE_IDS) : dedupedNativeIds;
|
|
1677
|
-
const sortedDays = [...update.days].sort();
|
|
1678
|
-
const latestDay = sortedDays[sortedDays.length - 1];
|
|
1679
|
-
const lastDateSynced = latestDay !== void 0 && (!previous || previous.lastDateSynced < latestDay) ? latestDay : previous?.lastDateSynced ?? latestDay ?? "";
|
|
1680
|
-
return {
|
|
1681
|
-
version: 1,
|
|
1682
|
-
sources: {
|
|
1683
|
-
...state.sources,
|
|
1684
|
-
[sourceId]: {
|
|
1685
|
-
lastSyncAt: update.syncedAt,
|
|
1686
|
-
lastDateSynced,
|
|
1687
|
-
dayHashes: mergedHashes,
|
|
1688
|
-
memoryDayHashes: mergedMemoryHashes,
|
|
1689
|
-
importedNativeMemoryIds: boundedNativeIds
|
|
1690
|
-
}
|
|
1691
|
-
}
|
|
1692
|
-
};
|
|
1693
|
-
}
|
|
1694
|
-
|
|
1695
|
-
// src/wearables/pipeline.ts
|
|
1696
|
-
var MAX_PAGES_PER_DAY = 50;
|
|
1697
|
-
var MAX_NATIVE_PAGES = 20;
|
|
1698
|
-
var DEFAULT_SYNC_DAYS = 2;
|
|
1699
|
-
var MAX_SYNC_DAYS = 90;
|
|
1700
|
-
function dateInTimezone(date, timezone) {
|
|
1701
|
-
try {
|
|
1702
|
-
const parts = new Intl.DateTimeFormat("en-CA", {
|
|
1703
|
-
timeZone: timezone,
|
|
1704
|
-
year: "numeric",
|
|
1705
|
-
month: "2-digit",
|
|
1706
|
-
day: "2-digit"
|
|
1707
|
-
}).formatToParts(date);
|
|
1708
|
-
const get = (type) => parts.find((part) => part.type === type)?.value ?? "";
|
|
1709
|
-
return `${get("year")}-${get("month")}-${get("day")}`;
|
|
1710
|
-
} catch {
|
|
1711
|
-
return date.toISOString().slice(0, 10);
|
|
1712
|
-
}
|
|
1713
|
-
}
|
|
1714
|
-
function resolveSyncDates(options, timezone, now) {
|
|
1715
|
-
if (options.date !== void 0) {
|
|
1716
|
-
if (!isValidTranscriptDate(options.date)) {
|
|
1717
|
-
throw new WearablesInputError(
|
|
1718
|
-
`wearables sync: invalid date '${options.date}' \u2014 expected YYYY-MM-DD`
|
|
1719
|
-
);
|
|
1720
|
-
}
|
|
1721
|
-
return [options.date];
|
|
1722
|
-
}
|
|
1723
|
-
let days = DEFAULT_SYNC_DAYS;
|
|
1724
|
-
if (options.days !== void 0) {
|
|
1725
|
-
if (!Number.isFinite(options.days) || !Number.isInteger(options.days) || options.days < 1 || options.days > MAX_SYNC_DAYS) {
|
|
1726
|
-
throw new WearablesInputError(
|
|
1727
|
-
`wearables sync: invalid days '${options.days}' \u2014 expected an integer between 1 and ${MAX_SYNC_DAYS}`
|
|
1728
|
-
);
|
|
1729
|
-
}
|
|
1730
|
-
days = options.days;
|
|
1731
|
-
}
|
|
1732
|
-
const dates = [];
|
|
1733
|
-
let cursor = dateInTimezone(now, timezone);
|
|
1734
|
-
for (let count = 0; count < days; count++) {
|
|
1735
|
-
dates.unshift(cursor);
|
|
1736
|
-
cursor = previousIsoDate(cursor);
|
|
1737
|
-
}
|
|
1738
|
-
return dates;
|
|
1739
|
-
}
|
|
1740
|
-
function previousIsoDate(date) {
|
|
1741
|
-
const parsed = /* @__PURE__ */ new Date(`${date}T00:00:00Z`);
|
|
1742
|
-
parsed.setUTCDate(parsed.getUTCDate() - 1);
|
|
1743
|
-
return parsed.toISOString().slice(0, 10);
|
|
1744
|
-
}
|
|
1745
|
-
async function fetchAllConversationsForDate(connector, date, timezone, signal, warnings) {
|
|
1746
|
-
const conversations = [];
|
|
1747
|
-
let cursor = void 0;
|
|
1748
|
-
for (let page = 0; page < MAX_PAGES_PER_DAY; page++) {
|
|
1749
|
-
const result = await connector.fetchConversations({
|
|
1750
|
-
date,
|
|
1751
|
-
timezone,
|
|
1752
|
-
cursor,
|
|
1753
|
-
signal
|
|
1754
|
-
});
|
|
1755
|
-
conversations.push(...result.conversations);
|
|
1756
|
-
if (!result.nextCursor) return { conversations, partial: false };
|
|
1757
|
-
cursor = result.nextCursor;
|
|
1758
|
-
}
|
|
1759
|
-
warnings.push(
|
|
1760
|
-
`${connector.id}: stopped paginating ${date} after ${MAX_PAGES_PER_DAY} pages \u2014 day may be partially synced (every sync refetches and re-warns until the provider day fits the cap)`
|
|
1761
|
-
);
|
|
1762
|
-
return { conversations, partial: true };
|
|
1763
|
-
}
|
|
1764
|
-
var PARTIAL_DAY_MARKER = "\n*Note: pagination safety cap reached during sync \u2014 this day may be incomplete.*\n";
|
|
1765
|
-
function emptyDayBody(sourceId, date) {
|
|
1766
|
-
return `# ${sourceId} transcript \u2014 ${date}
|
|
1767
|
-
|
|
1768
|
-
_No storable conversation content for this day (all segments were elided or dropped)._
|
|
1769
|
-
`;
|
|
1770
|
-
}
|
|
1771
|
-
function cleanDay(raw, sourceId, settings, config, userRedaction, correctionRules) {
|
|
1772
|
-
const out = {
|
|
1773
|
-
conversations: [],
|
|
1774
|
-
segmentsKept: 0,
|
|
1775
|
-
segmentsDropped: 0,
|
|
1776
|
-
redactions: 0,
|
|
1777
|
-
correctionsApplied: 0
|
|
1778
|
-
};
|
|
1779
|
-
for (const conversation of raw) {
|
|
1780
|
-
let current = conversation;
|
|
1781
|
-
if (config.offTheRecordEnabled) {
|
|
1782
|
-
const otr = applyOffTheRecord(current);
|
|
1783
|
-
current = otr.conversation;
|
|
1784
|
-
out.segmentsDropped += otr.droppedSegments;
|
|
1785
|
-
}
|
|
1786
|
-
const cleaned = cleanConversation(current, settings.cleanup);
|
|
1787
|
-
current = cleaned.conversation;
|
|
1788
|
-
out.segmentsDropped += cleaned.droppedSegments;
|
|
1789
|
-
const segments = current.segments.map((segment) => {
|
|
1790
|
-
let text = segment.text;
|
|
1791
|
-
if (config.redactionEnabled) {
|
|
1792
|
-
const redacted = redactText(text, userRedaction);
|
|
1793
|
-
text = redacted.text;
|
|
1794
|
-
out.redactions += redacted.redactions;
|
|
1795
|
-
}
|
|
1796
|
-
const corrected = applyCorrections(text, correctionRules, sourceId);
|
|
1797
|
-
out.correctionsApplied += corrected.applied;
|
|
1798
|
-
return { ...segment, text: corrected.text };
|
|
1799
|
-
});
|
|
1800
|
-
current = { ...current, segments };
|
|
1801
|
-
if (current.segments.length > 0) {
|
|
1802
|
-
out.conversations.push(current);
|
|
1803
|
-
out.segmentsKept += current.segments.length;
|
|
1804
|
-
}
|
|
1805
|
-
}
|
|
1806
|
-
return out;
|
|
1807
|
-
}
|
|
1808
|
-
async function syncWearableSource(connector, settings, config, options, deps) {
|
|
1809
|
-
const now = deps.now ? deps.now() : /* @__PURE__ */ new Date();
|
|
1810
|
-
const timezone = config.timezone ?? defaultTimezone();
|
|
1811
|
-
const dates = resolveSyncDates(options, timezone, now);
|
|
1812
|
-
const summary = {
|
|
1813
|
-
source: connector.id,
|
|
1814
|
-
days: dates,
|
|
1815
|
-
conversations: 0,
|
|
1816
|
-
segmentsKept: 0,
|
|
1817
|
-
segmentsDropped: 0,
|
|
1818
|
-
redactions: 0,
|
|
1819
|
-
correctionsApplied: 0,
|
|
1820
|
-
transcriptsWritten: [],
|
|
1821
|
-
memoriesCreated: 0,
|
|
1822
|
-
memoriesPromoted: 0,
|
|
1823
|
-
memoriesDemoted: 0,
|
|
1824
|
-
memoriesSkipped: 0,
|
|
1825
|
-
nativeMemoriesImported: 0,
|
|
1826
|
-
warnings: []
|
|
1827
|
-
};
|
|
1828
|
-
const registry = await loadSpeakerRegistry(deps.memoryDir);
|
|
1829
|
-
const stateRules = await loadCorrectionsFile(deps.memoryDir);
|
|
1830
|
-
const correctionRules = [
|
|
1831
|
-
...compileCorrectionRules(config.corrections, "wearables.corrections"),
|
|
1832
|
-
...compileCorrectionRules(stateRules, "state corrections")
|
|
1833
|
-
];
|
|
1834
|
-
const userRedaction = compileRedactionPatterns(config.redactionPatterns);
|
|
1835
|
-
let syncState = await loadSyncState(deps.memoryDir);
|
|
1836
|
-
const previousState = syncState.sources[connector.id];
|
|
1837
|
-
const dayHashes = {};
|
|
1838
|
-
const memoryDayHashes = {};
|
|
1839
|
-
const failedMemoryDays = [];
|
|
1840
|
-
const importedNativeIds = [];
|
|
1841
|
-
for (const date of dates) {
|
|
1842
|
-
const fetched = await fetchAllConversationsForDate(
|
|
1843
|
-
connector,
|
|
1844
|
-
date,
|
|
1845
|
-
timezone,
|
|
1846
|
-
options.signal,
|
|
1847
|
-
summary.warnings
|
|
1848
|
-
);
|
|
1849
|
-
const cleaned = cleanDay(
|
|
1850
|
-
fetched.conversations,
|
|
1851
|
-
connector.id,
|
|
1852
|
-
settings,
|
|
1853
|
-
config,
|
|
1854
|
-
userRedaction,
|
|
1855
|
-
correctionRules
|
|
1856
|
-
);
|
|
1857
|
-
summary.conversations += cleaned.conversations.length;
|
|
1858
|
-
summary.segmentsKept += cleaned.segmentsKept;
|
|
1859
|
-
summary.segmentsDropped += cleaned.segmentsDropped;
|
|
1860
|
-
summary.redactions += cleaned.redactions;
|
|
1861
|
-
summary.correctionsApplied += cleaned.correctionsApplied;
|
|
1862
|
-
if (fetched.conversations.length === 0) {
|
|
1863
|
-
const existing = await deps.readDayContentHash(connector.id, date);
|
|
1864
|
-
if (existing !== null) {
|
|
1865
|
-
summary.warnings.push(
|
|
1866
|
-
`${connector.id}: provider returned no conversations for ${date} but a stored transcript exists \u2014 leaving it in place; delete the day file manually if the recordings were intentionally removed upstream`
|
|
1867
|
-
);
|
|
1868
|
-
}
|
|
1869
|
-
continue;
|
|
1870
|
-
}
|
|
1871
|
-
const allElided = cleaned.conversations.length === 0;
|
|
1872
|
-
let body = allElided ? emptyDayBody(connector.id, date) : composeDayTranscriptBody(
|
|
1873
|
-
connector.id,
|
|
1874
|
-
date,
|
|
1875
|
-
timezone,
|
|
1876
|
-
cleaned.conversations,
|
|
1877
|
-
registry
|
|
1878
|
-
);
|
|
1879
|
-
if (fetched.partial && !allElided) {
|
|
1880
|
-
body += PARTIAL_DAY_MARKER;
|
|
1881
|
-
}
|
|
1882
|
-
const bodyHash = hashTranscriptBody(body);
|
|
1883
|
-
const existingHash = await deps.readDayContentHash(connector.id, date);
|
|
1884
|
-
const changed = existingHash !== bodyHash;
|
|
1885
|
-
const shouldWrite = changed && (!allElided || existingHash !== null);
|
|
1886
|
-
if (shouldWrite) {
|
|
1887
|
-
const meta = composeDayTranscriptMeta(
|
|
1888
|
-
connector.id,
|
|
1889
|
-
date,
|
|
1890
|
-
timezone,
|
|
1891
|
-
cleaned.conversations,
|
|
1892
|
-
registry,
|
|
1893
|
-
body,
|
|
1894
|
-
now.toISOString()
|
|
1895
|
-
);
|
|
1896
|
-
await deps.writeDayTranscript(
|
|
1897
|
-
connector.id,
|
|
1898
|
-
date,
|
|
1899
|
-
serializeDayTranscript(meta, body)
|
|
1900
|
-
);
|
|
1901
|
-
summary.transcriptsWritten.push(date);
|
|
1902
|
-
}
|
|
1903
|
-
dayHashes[date] = bodyHash;
|
|
1904
|
-
if (allElided) continue;
|
|
1905
|
-
const needsSmartContext = settings.memoryMode === "smart" || settings.importNativeMemories === "smart";
|
|
1906
|
-
const memoryPassComplete = previousState?.memoryDayHashes?.[date] === bodyHash;
|
|
1907
|
-
if (settings.memoryMode !== "off" && (changed || options.forceMemories === true || !memoryPassComplete)) {
|
|
1908
|
-
if (!deps.memoryGen) {
|
|
1909
|
-
summary.warnings.push(
|
|
1910
|
-
`${connector.id}: memoryMode is '${settings.memoryMode}' but no extraction engine is available in this context \u2014 transcripts synced, memories skipped`
|
|
1911
|
-
);
|
|
1912
|
-
} else {
|
|
1913
|
-
let passClean = false;
|
|
1914
|
-
try {
|
|
1915
|
-
const corroboration = needsSmartContext ? await buildCorroborationContext(connector.id, date, deps) : void 0;
|
|
1916
|
-
const dayMemoryGen = {
|
|
1917
|
-
...deps.memoryGen,
|
|
1918
|
-
...corroboration !== void 0 ? { corroboration } : {}
|
|
1919
|
-
};
|
|
1920
|
-
const generated = await generateWearableMemories(
|
|
1921
|
-
connector.id,
|
|
1922
|
-
date,
|
|
1923
|
-
cleaned.conversations,
|
|
1924
|
-
settings,
|
|
1925
|
-
registry,
|
|
1926
|
-
dayMemoryGen
|
|
1927
|
-
);
|
|
1928
|
-
summary.memoriesCreated += generated.created;
|
|
1929
|
-
summary.memoriesPromoted += generated.promoted;
|
|
1930
|
-
summary.memoriesDemoted += generated.demoted;
|
|
1931
|
-
summary.memoriesSkipped += generated.skipped;
|
|
1932
|
-
summary.warnings.push(...generated.warnings);
|
|
1933
|
-
passClean = generated.completed;
|
|
1934
|
-
if (config.digestEnabled) {
|
|
1935
|
-
const wrote = await writeDailyDigestMemory(
|
|
1936
|
-
connector.id,
|
|
1937
|
-
date,
|
|
1938
|
-
cleaned.conversations,
|
|
1939
|
-
settings,
|
|
1940
|
-
registry,
|
|
1941
|
-
deps.memoryGen.writer
|
|
1942
|
-
);
|
|
1943
|
-
if (wrote) summary.memoriesCreated += 1;
|
|
1944
|
-
}
|
|
1945
|
-
} catch (err) {
|
|
1946
|
-
passClean = false;
|
|
1947
|
-
summary.warnings.push(
|
|
1948
|
-
`${connector.id}: memory pass failed for ${date}: ${describeErrorForOperator(err)} \u2014 retries on the next sync`
|
|
1949
|
-
);
|
|
1950
|
-
}
|
|
1951
|
-
if (passClean) {
|
|
1952
|
-
memoryDayHashes[date] = bodyHash;
|
|
1953
|
-
} else {
|
|
1954
|
-
failedMemoryDays.push(date);
|
|
1955
|
-
}
|
|
1956
|
-
}
|
|
1957
|
-
} else if (settings.memoryMode !== "off" && memoryPassComplete) {
|
|
1958
|
-
memoryDayHashes[date] = bodyHash;
|
|
1959
|
-
}
|
|
1960
|
-
}
|
|
1961
|
-
if (settings.importNativeMemories !== "off" && typeof connector.fetchNativeMemories === "function") {
|
|
1962
|
-
if (!deps.memoryGen) {
|
|
1963
|
-
summary.warnings.push(
|
|
1964
|
-
`${connector.id}: importNativeMemories is enabled but no memory writer is available in this context`
|
|
1965
|
-
);
|
|
1966
|
-
} else {
|
|
1967
|
-
const alreadyImported = new Set(
|
|
1968
|
-
previousState?.importedNativeMemoryIds ?? []
|
|
1969
|
-
);
|
|
1970
|
-
const nativeCorroboration = settings.importNativeMemories === "smart" ? {
|
|
1971
|
-
otherSourceDayTokens: /* @__PURE__ */ new Map(),
|
|
1972
|
-
existingMemories: deps.listSupportMemories ? await deps.listSupportMemories() : []
|
|
1973
|
-
} : void 0;
|
|
1974
|
-
const nativeMemoryGen = {
|
|
1975
|
-
...deps.memoryGen,
|
|
1976
|
-
...nativeCorroboration !== void 0 ? { corroboration: nativeCorroboration } : {}
|
|
1977
|
-
};
|
|
1978
|
-
let cursor = void 0;
|
|
1979
|
-
for (let page = 0; page < MAX_NATIVE_PAGES; page++) {
|
|
1980
|
-
const result = await connector.fetchNativeMemories({
|
|
1981
|
-
cursor,
|
|
1982
|
-
signal: options.signal
|
|
1983
|
-
});
|
|
1984
|
-
const imported = await importNativeMemories(
|
|
1985
|
-
connector.id,
|
|
1986
|
-
result.memories,
|
|
1987
|
-
alreadyImported,
|
|
1988
|
-
settings,
|
|
1989
|
-
nativeMemoryGen
|
|
1990
|
-
);
|
|
1991
|
-
summary.warnings.push(...imported.warnings);
|
|
1992
|
-
summary.nativeMemoriesImported += imported.imported;
|
|
1993
|
-
importedNativeIds.push(...imported.importedIds);
|
|
1994
|
-
for (const id of imported.importedIds) alreadyImported.add(id);
|
|
1995
|
-
if (!result.nextCursor) break;
|
|
1996
|
-
cursor = result.nextCursor;
|
|
1997
|
-
if (page === MAX_NATIVE_PAGES - 1) {
|
|
1998
|
-
summary.warnings.push(
|
|
1999
|
-
`${connector.id}: stopped native-memory import after ${MAX_NATIVE_PAGES} pages \u2014 remaining items import on the next sync`
|
|
2000
|
-
);
|
|
2001
|
-
}
|
|
2002
|
-
}
|
|
2003
|
-
}
|
|
2004
|
-
}
|
|
2005
|
-
const wroteAnything = summary.transcriptsWritten.length > 0 || summary.memoriesCreated > 0 || summary.memoriesPromoted > 0 || summary.memoriesDemoted > 0 || summary.nativeMemoriesImported > 0;
|
|
2006
|
-
if (wroteAnything && deps.afterWrites) {
|
|
2007
|
-
try {
|
|
2008
|
-
await deps.afterWrites();
|
|
2009
|
-
} catch (err) {
|
|
2010
|
-
summary.warnings.push(
|
|
2011
|
-
`search reindex failed (writes are stored and will index on the next update): ${describeErrorForOperator(err)}`
|
|
2012
|
-
);
|
|
2013
|
-
}
|
|
2014
|
-
}
|
|
2015
|
-
syncState = updateSourceSyncState(syncState, connector.id, {
|
|
2016
|
-
syncedAt: now.toISOString(),
|
|
2017
|
-
days: dates,
|
|
2018
|
-
dayHashes,
|
|
2019
|
-
memoryDayHashes,
|
|
2020
|
-
clearMemoryDays: failedMemoryDays,
|
|
2021
|
-
importedNativeMemoryIds: importedNativeIds
|
|
2022
|
-
});
|
|
2023
|
-
if (summary.transcriptsWritten.length > 0) {
|
|
2024
|
-
const cleared = {};
|
|
2025
|
-
for (const [otherId, otherState] of Object.entries(syncState.sources)) {
|
|
2026
|
-
if (otherId === connector.id || otherState.memoryDayHashes === void 0) {
|
|
2027
|
-
cleared[otherId] = otherState;
|
|
2028
|
-
continue;
|
|
2029
|
-
}
|
|
2030
|
-
const memoryDays = { ...otherState.memoryDayHashes };
|
|
2031
|
-
let touched = false;
|
|
2032
|
-
for (const date of summary.transcriptsWritten) {
|
|
2033
|
-
if (date in memoryDays) {
|
|
2034
|
-
delete memoryDays[date];
|
|
2035
|
-
touched = true;
|
|
2036
|
-
}
|
|
2037
|
-
}
|
|
2038
|
-
cleared[otherId] = touched ? { ...otherState, memoryDayHashes: memoryDays } : otherState;
|
|
2039
|
-
}
|
|
2040
|
-
syncState = { version: 1, sources: cleared };
|
|
2041
|
-
}
|
|
2042
|
-
await saveSyncState(deps.memoryDir, syncState);
|
|
2043
|
-
return summary;
|
|
2044
|
-
}
|
|
2045
|
-
async function buildCorroborationContext(sourceId, date, deps) {
|
|
2046
|
-
const otherSourceDayTokens = /* @__PURE__ */ new Map();
|
|
2047
|
-
if (deps.readOtherSourceDayBodies) {
|
|
2048
|
-
const bodies = await deps.readOtherSourceDayBodies(date, sourceId);
|
|
2049
|
-
for (const [otherSource, body] of bodies) {
|
|
2050
|
-
otherSourceDayTokens.set(otherSource, tokenizeDayBody(body));
|
|
2051
|
-
}
|
|
2052
|
-
}
|
|
2053
|
-
const existingMemories = deps.listSupportMemories ? await deps.listSupportMemories() : [];
|
|
2054
|
-
return { otherSourceDayTokens, existingMemories };
|
|
2055
|
-
}
|
|
2056
|
-
function defaultTimezone() {
|
|
2057
|
-
try {
|
|
2058
|
-
return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
|
|
2059
|
-
} catch {
|
|
2060
|
-
return "UTC";
|
|
2061
|
-
}
|
|
2062
|
-
}
|
|
2063
|
-
|
|
2064
969
|
// src/wearables/registry.ts
|
|
2065
970
|
var registrations = /* @__PURE__ */ new Map();
|
|
2066
971
|
function registerWearableConnector(registration) {
|
|
@@ -2763,7 +1668,7 @@ async function qmdStartupCollectionCheckWithTimeout(promise, controller, label)
|
|
|
2763
1668
|
return await Promise.race([checkedPromise, timeoutPromise]);
|
|
2764
1669
|
}
|
|
2765
1670
|
function defaultWorkspaceDir() {
|
|
2766
|
-
return
|
|
1671
|
+
return path2.join(os.homedir(), ".openclaw", "workspace");
|
|
2767
1672
|
}
|
|
2768
1673
|
function sanitizeSessionKeyForFilename(sessionKey) {
|
|
2769
1674
|
const readable = sessionKey.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
@@ -3072,11 +1977,11 @@ function mergeGraphExpandedResults(primary, expanded) {
|
|
|
3072
1977
|
return Array.from(mergedByPath.values());
|
|
3073
1978
|
}
|
|
3074
1979
|
function graphPathRelativeToStorage(storageDir, candidatePath) {
|
|
3075
|
-
const absolutePath =
|
|
3076
|
-
const rel =
|
|
1980
|
+
const absolutePath = path2.isAbsolute(candidatePath) ? candidatePath : path2.resolve(storageDir, candidatePath);
|
|
1981
|
+
const rel = path2.relative(storageDir, absolutePath);
|
|
3077
1982
|
if (!rel || rel === ".") return null;
|
|
3078
1983
|
if (rel.startsWith("..")) return null;
|
|
3079
|
-
return rel.split(
|
|
1984
|
+
return rel.split(path2.sep).join("/");
|
|
3080
1985
|
}
|
|
3081
1986
|
function normalizeGraphActivationScore(score) {
|
|
3082
1987
|
const bounded = Number.isFinite(score) && score > 0 ? score : 0;
|
|
@@ -3218,7 +2123,7 @@ function buildMemoryPathById(allMemsForGraph, storageDir) {
|
|
|
3218
2123
|
for (const mem of allMemsForGraph ?? []) {
|
|
3219
2124
|
const id = mem.frontmatter.id;
|
|
3220
2125
|
if (!id) continue;
|
|
3221
|
-
pathById.set(id,
|
|
2126
|
+
pathById.set(id, path2.relative(storageDir, mem.path));
|
|
3222
2127
|
}
|
|
3223
2128
|
return pathById;
|
|
3224
2129
|
}
|
|
@@ -3226,7 +2131,7 @@ function appendMemoryToGraphContext(options) {
|
|
|
3226
2131
|
if (!Array.isArray(options.allMemsForGraph)) return;
|
|
3227
2132
|
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
3228
2133
|
options.allMemsForGraph.push({
|
|
3229
|
-
path:
|
|
2134
|
+
path: path2.join(options.storageDir, options.memoryRelPath),
|
|
3230
2135
|
content: options.content,
|
|
3231
2136
|
frontmatter: {
|
|
3232
2137
|
id: options.memoryId,
|
|
@@ -3246,16 +2151,16 @@ function resolvePersistedMemoryRelativePath(options) {
|
|
|
3246
2151
|
const persisted = options.pathById.get(options.memoryId);
|
|
3247
2152
|
if (persisted) return persisted;
|
|
3248
2153
|
if (options.category === "correction") {
|
|
3249
|
-
return
|
|
2154
|
+
return path2.join("corrections", `${options.memoryId}.md`);
|
|
3250
2155
|
}
|
|
3251
2156
|
const subtree = options.category === "procedure" ? "procedures" : options.category === "reasoning_trace" ? "reasoning-traces" : "facts";
|
|
3252
2157
|
const idParts = options.memoryId.split("-");
|
|
3253
2158
|
const maybeTimestamp = Number(idParts[1]);
|
|
3254
2159
|
if (Number.isFinite(maybeTimestamp) && maybeTimestamp > 0) {
|
|
3255
2160
|
const day = new Date(maybeTimestamp).toISOString().slice(0, 10);
|
|
3256
|
-
return
|
|
2161
|
+
return path2.join(subtree, day, `${options.memoryId}.md`);
|
|
3257
2162
|
}
|
|
3258
|
-
return
|
|
2163
|
+
return path2.join(subtree, `${options.memoryId}.md`);
|
|
3259
2164
|
}
|
|
3260
2165
|
var Orchestrator = class _Orchestrator {
|
|
3261
2166
|
storage;
|
|
@@ -3375,6 +2280,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
3375
2280
|
consolidationObservers = /* @__PURE__ */ new Set();
|
|
3376
2281
|
qmdMaintenanceTimer = null;
|
|
3377
2282
|
wearablesServiceInstance = null;
|
|
2283
|
+
wearablesAutoSyncHandle = null;
|
|
3378
2284
|
qmdMaintenancePending = false;
|
|
3379
2285
|
qmdMaintenanceInFlight = false;
|
|
3380
2286
|
lastQmdEmbedAtMs = 0;
|
|
@@ -3449,6 +2355,10 @@ var Orchestrator = class _Orchestrator {
|
|
|
3449
2355
|
*/
|
|
3450
2356
|
async destroy() {
|
|
3451
2357
|
this.abortDeferredInit();
|
|
2358
|
+
if (this.wearablesAutoSyncHandle) {
|
|
2359
|
+
await this.wearablesAutoSyncHandle.stop();
|
|
2360
|
+
this.wearablesAutoSyncHandle = null;
|
|
2361
|
+
}
|
|
3452
2362
|
if (this.qmdMaintenanceTimer) {
|
|
3453
2363
|
clearTimeout(this.qmdMaintenanceTimer);
|
|
3454
2364
|
this.qmdMaintenanceTimer = null;
|
|
@@ -3693,7 +2603,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
3693
2603
|
this.config = config;
|
|
3694
2604
|
this.profiler = new ProfilingCollector({
|
|
3695
2605
|
enabled: config.profilingEnabled,
|
|
3696
|
-
storageDir: config.profilingStorageDir ||
|
|
2606
|
+
storageDir: config.profilingStorageDir || path2.join(config.memoryDir, "profiling"),
|
|
3697
2607
|
maxTraces: config.profilingMaxTraces
|
|
3698
2608
|
});
|
|
3699
2609
|
this.storageRouter = new NamespaceStorageRouter(config);
|
|
@@ -3728,7 +2638,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
3728
2638
|
this.compounding = config.compoundingEnabled ? new CompoundingEngine(config, this.storage) : void 0;
|
|
3729
2639
|
this.buffer = new SmartBuffer(config, this.storage);
|
|
3730
2640
|
this.transcript = new TranscriptManager(config);
|
|
3731
|
-
this.conversationIndexDir =
|
|
2641
|
+
this.conversationIndexDir = path2.join(
|
|
3732
2642
|
config.memoryDir,
|
|
3733
2643
|
"conversation-index",
|
|
3734
2644
|
"chunks"
|
|
@@ -3785,7 +2695,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
3785
2695
|
this.modelRegistry
|
|
3786
2696
|
);
|
|
3787
2697
|
this.threading = new ThreadingManager(
|
|
3788
|
-
|
|
2698
|
+
path2.join(config.memoryDir, "threads"),
|
|
3789
2699
|
config.threadingGapMinutes
|
|
3790
2700
|
);
|
|
3791
2701
|
this.tmtBuilder = new TmtBuilder(config.memoryDir, {
|
|
@@ -4083,7 +2993,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4083
2993
|
const files = await readdir(wsDir).catch(() => []);
|
|
4084
2994
|
for (const f of files) {
|
|
4085
2995
|
if (!f.startsWith(".compaction-reset-signal-")) continue;
|
|
4086
|
-
const fp =
|
|
2996
|
+
const fp = path2.join(wsDir, f);
|
|
4087
2997
|
const s = await stat(fp).catch(() => null);
|
|
4088
2998
|
if (s && Date.now() - s.mtimeMs >= COMPACTION_SIGNAL_MAX_AGE_MS) {
|
|
4089
2999
|
await unlink(fp).catch(() => {
|
|
@@ -4338,6 +3248,36 @@ var Orchestrator = class _Orchestrator {
|
|
|
4338
3248
|
log.warn(`first-start lifecycle migration failed (non-fatal): ${err}`);
|
|
4339
3249
|
}
|
|
4340
3250
|
}
|
|
3251
|
+
if (signal.aborted) return;
|
|
3252
|
+
if (!this.wearablesAutoSyncHandle && this.config.wearables.enabled && this.config.wearables.autoSyncEnabled && Object.values(this.config.wearables.sources).some((source) => source.enabled)) {
|
|
3253
|
+
try {
|
|
3254
|
+
const { startWearablesAutoSync } = await import("./auto-sync-RFADEHIQ.js");
|
|
3255
|
+
if (signal.aborted) return;
|
|
3256
|
+
this.wearablesAutoSyncHandle = startWearablesAutoSync(
|
|
3257
|
+
{
|
|
3258
|
+
intervalMinutes: this.config.wearables.autoSyncIntervalMinutes,
|
|
3259
|
+
days: this.config.wearables.autoSyncDays,
|
|
3260
|
+
deepDays: this.config.wearables.autoSyncDeepDays,
|
|
3261
|
+
...this.config.wearables.timezone !== void 0 ? { timezone: this.config.wearables.timezone } : {}
|
|
3262
|
+
},
|
|
3263
|
+
{
|
|
3264
|
+
sync: (options) => this.getWearablesService().sync(options),
|
|
3265
|
+
log: {
|
|
3266
|
+
info: (message) => log.info(message),
|
|
3267
|
+
warn: (message) => log.warn(message)
|
|
3268
|
+
}
|
|
3269
|
+
}
|
|
3270
|
+
);
|
|
3271
|
+
log.info(
|
|
3272
|
+
`wearables auto-sync started: every ${this.config.wearables.autoSyncIntervalMinutes}m over ${this.config.wearables.autoSyncDays}d (deep ${this.config.wearables.autoSyncDeepDays}d daily)`
|
|
3273
|
+
);
|
|
3274
|
+
} catch (err) {
|
|
3275
|
+
const { displayErrorDetail } = await import("./runtime/better-sqlite.js");
|
|
3276
|
+
log.warn(
|
|
3277
|
+
`wearables auto-sync failed to start (non-fatal): ${displayErrorDetail(err)}`
|
|
3278
|
+
);
|
|
3279
|
+
}
|
|
3280
|
+
}
|
|
4341
3281
|
log.info("orchestrator initialized (full \u2014 deferred steps complete)");
|
|
4342
3282
|
}
|
|
4343
3283
|
/**
|
|
@@ -4445,7 +3385,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4445
3385
|
*/
|
|
4446
3386
|
async autoRegisterDaySummaryCron() {
|
|
4447
3387
|
const home = resolveHomeDir();
|
|
4448
|
-
const jobsPath =
|
|
3388
|
+
const jobsPath = path2.join(home, ".openclaw", "cron", "jobs.json");
|
|
4449
3389
|
try {
|
|
4450
3390
|
if (!existsSync(jobsPath)) {
|
|
4451
3391
|
log.debug(
|
|
@@ -4469,7 +3409,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4469
3409
|
}
|
|
4470
3410
|
async autoRegisterNightlyGovernanceCron() {
|
|
4471
3411
|
const home = resolveHomeDir();
|
|
4472
|
-
const jobsPath =
|
|
3412
|
+
const jobsPath = path2.join(home, ".openclaw", "cron", "jobs.json");
|
|
4473
3413
|
try {
|
|
4474
3414
|
if (!existsSync(jobsPath)) {
|
|
4475
3415
|
log.debug("nightly governance cron: jobs.json not found, skipping auto-register");
|
|
@@ -4491,7 +3431,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4491
3431
|
}
|
|
4492
3432
|
async autoRegisterProceduralMiningCron() {
|
|
4493
3433
|
const home = resolveHomeDir();
|
|
4494
|
-
const jobsPath =
|
|
3434
|
+
const jobsPath = path2.join(home, ".openclaw", "cron", "jobs.json");
|
|
4495
3435
|
try {
|
|
4496
3436
|
if (!existsSync(jobsPath)) {
|
|
4497
3437
|
log.debug("procedural mining cron: jobs.json not found, skipping auto-register");
|
|
@@ -4511,7 +3451,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4511
3451
|
}
|
|
4512
3452
|
async autoRegisterContradictionScanCron() {
|
|
4513
3453
|
const home = resolveHomeDir();
|
|
4514
|
-
const jobsPath =
|
|
3454
|
+
const jobsPath = path2.join(home, ".openclaw", "cron", "jobs.json");
|
|
4515
3455
|
try {
|
|
4516
3456
|
if (!existsSync(jobsPath)) {
|
|
4517
3457
|
log.debug("contradiction scan cron: jobs.json not found, skipping auto-register");
|
|
@@ -4531,7 +3471,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4531
3471
|
}
|
|
4532
3472
|
async autoRegisterPatternReinforcementCron() {
|
|
4533
3473
|
const home = resolveHomeDir();
|
|
4534
|
-
const jobsPath =
|
|
3474
|
+
const jobsPath = path2.join(home, ".openclaw", "cron", "jobs.json");
|
|
4535
3475
|
try {
|
|
4536
3476
|
if (!existsSync(jobsPath)) {
|
|
4537
3477
|
log.debug("pattern reinforcement cron: jobs.json not found, skipping auto-register");
|
|
@@ -4593,7 +3533,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4593
3533
|
}
|
|
4594
3534
|
async autoRegisterGraphEdgeDecayCron() {
|
|
4595
3535
|
const home = resolveHomeDir();
|
|
4596
|
-
const jobsPath =
|
|
3536
|
+
const jobsPath = path2.join(home, ".openclaw", "cron", "jobs.json");
|
|
4597
3537
|
try {
|
|
4598
3538
|
if (!existsSync(jobsPath)) {
|
|
4599
3539
|
log.debug("graph edge decay cron: jobs.json not found, skipping auto-register");
|
|
@@ -4650,15 +3590,15 @@ ${doc.content}` : doc.content,
|
|
|
4650
3590
|
this.lastFileHygieneRunAtMs = now;
|
|
4651
3591
|
if (hygiene.rotateEnabled) {
|
|
4652
3592
|
for (const rel of hygiene.rotatePaths) {
|
|
4653
|
-
const abs =
|
|
3593
|
+
const abs = path2.isAbsolute(rel) ? rel : path2.join(this.config.workspaceDir, rel);
|
|
4654
3594
|
try {
|
|
4655
3595
|
const raw = await readFile2(abs, "utf-8");
|
|
4656
3596
|
if (raw.length > hygiene.rotateMaxBytes) {
|
|
4657
|
-
const archiveDir =
|
|
3597
|
+
const archiveDir = path2.join(
|
|
4658
3598
|
this.config.workspaceDir,
|
|
4659
3599
|
hygiene.archiveDir
|
|
4660
3600
|
);
|
|
4661
|
-
const base =
|
|
3601
|
+
const base = path2.basename(abs);
|
|
4662
3602
|
const prefix = base.toUpperCase().replace(/\.MD$/i, "").replace(/[^A-Z0-9]+/g, "-") || "FILE";
|
|
4663
3603
|
const { newContent } = await rotateMarkdownFileToArchive({
|
|
4664
3604
|
filePath: abs,
|
|
@@ -4683,8 +3623,8 @@ ${doc.content}` : doc.content,
|
|
|
4683
3623
|
log.warn(w.message);
|
|
4684
3624
|
}
|
|
4685
3625
|
if (hygiene.warningsLogEnabled && warnings.length > 0) {
|
|
4686
|
-
const fp =
|
|
4687
|
-
await mkdir2(
|
|
3626
|
+
const fp = path2.join(this.config.memoryDir, hygiene.warningsLogPath);
|
|
3627
|
+
await mkdir2(path2.dirname(fp), { recursive: true });
|
|
4688
3628
|
const stamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
4689
3629
|
const block = `
|
|
4690
3630
|
|
|
@@ -5153,16 +4093,16 @@ ${evidenceText}`
|
|
|
5153
4093
|
const datesToScan = [yesterday, utcToday].filter(
|
|
5154
4094
|
(v, i, a) => a.indexOf(v) === i
|
|
5155
4095
|
);
|
|
5156
|
-
const factsBaseDir =
|
|
4096
|
+
const factsBaseDir = path2.join(storage.dir, "facts");
|
|
5157
4097
|
const MAX_CHARS = 1e5;
|
|
5158
4098
|
const facts = [];
|
|
5159
4099
|
for (const date of datesToScan) {
|
|
5160
|
-
const factsDir =
|
|
4100
|
+
const factsDir = path2.join(factsBaseDir, date);
|
|
5161
4101
|
try {
|
|
5162
4102
|
const entries = await readdir(factsDir, { withFileTypes: true });
|
|
5163
4103
|
for (const entry of entries) {
|
|
5164
4104
|
if (!entry.name.endsWith(".md")) continue;
|
|
5165
|
-
const fullPath =
|
|
4105
|
+
const fullPath = path2.join(factsDir, entry.name);
|
|
5166
4106
|
try {
|
|
5167
4107
|
const raw = await readFile2(fullPath, "utf-8");
|
|
5168
4108
|
const fmMatch = raw.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
|
|
@@ -5178,7 +4118,7 @@ ${evidenceText}`
|
|
|
5178
4118
|
facts.push({
|
|
5179
4119
|
path: fullPath,
|
|
5180
4120
|
frontmatter: {
|
|
5181
|
-
id: fm.id ||
|
|
4121
|
+
id: fm.id || path2.basename(entry.name, ".md"),
|
|
5182
4122
|
category: fm.category || "fact",
|
|
5183
4123
|
created: fm.created || "unknown",
|
|
5184
4124
|
updated: fm.updated || fm.created || "unknown",
|
|
@@ -5199,13 +4139,13 @@ ${evidenceText}`
|
|
|
5199
4139
|
(a, b) => a.frontmatter.created < b.frontmatter.created ? -1 : 1
|
|
5200
4140
|
);
|
|
5201
4141
|
const hourlySummaries = [];
|
|
5202
|
-
const hourlyBaseDir =
|
|
4142
|
+
const hourlyBaseDir = path2.join(storage.dir, "summaries", "hourly");
|
|
5203
4143
|
try {
|
|
5204
4144
|
const sessionKeys = await readdir(hourlyBaseDir, { withFileTypes: true });
|
|
5205
4145
|
for (const sk of sessionKeys) {
|
|
5206
4146
|
if (!sk.isDirectory()) continue;
|
|
5207
4147
|
for (const date of datesToScan) {
|
|
5208
|
-
const summaryFile =
|
|
4148
|
+
const summaryFile = path2.join(hourlyBaseDir, sk.name, `${date}.md`);
|
|
5209
4149
|
try {
|
|
5210
4150
|
const raw = await readFile2(summaryFile, "utf-8");
|
|
5211
4151
|
if (raw.trim().length > 0) {
|
|
@@ -5303,7 +4243,7 @@ ${evidenceText}`
|
|
|
5303
4243
|
}
|
|
5304
4244
|
async getLastGraphRecallSnapshot(namespace) {
|
|
5305
4245
|
const storage = await this.getStorage(namespace);
|
|
5306
|
-
const snapshotPath =
|
|
4246
|
+
const snapshotPath = path2.join(
|
|
5307
4247
|
storage.dir,
|
|
5308
4248
|
"state",
|
|
5309
4249
|
"last_graph_recall.json"
|
|
@@ -5342,7 +4282,7 @@ ${evidenceText}`
|
|
|
5342
4282
|
}
|
|
5343
4283
|
async getLastIntentSnapshot(namespace) {
|
|
5344
4284
|
const storage = await this.getStorage(namespace);
|
|
5345
|
-
const snapshotPath =
|
|
4285
|
+
const snapshotPath = path2.join(storage.dir, "state", "last_intent.json");
|
|
5346
4286
|
try {
|
|
5347
4287
|
const raw = await readFile2(snapshotPath, "utf-8");
|
|
5348
4288
|
const parsed = JSON.parse(raw);
|
|
@@ -5375,7 +4315,7 @@ ${evidenceText}`
|
|
|
5375
4315
|
}
|
|
5376
4316
|
async getLastQmdRecallSnapshot(namespace) {
|
|
5377
4317
|
const storage = await this.getStorage(namespace);
|
|
5378
|
-
const snapshotPath =
|
|
4318
|
+
const snapshotPath = path2.join(
|
|
5379
4319
|
storage.dir,
|
|
5380
4320
|
"state",
|
|
5381
4321
|
"last_qmd_recall.json"
|
|
@@ -5528,7 +4468,7 @@ ${r.snippet.trim()}
|
|
|
5528
4468
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
5529
4469
|
let total = 0;
|
|
5530
4470
|
for (const entry of entries) {
|
|
5531
|
-
const fullPath =
|
|
4471
|
+
const fullPath = path2.join(dir, entry.name);
|
|
5532
4472
|
if (entry.isDirectory()) {
|
|
5533
4473
|
total += await this.countConversationChunkDocs(fullPath);
|
|
5534
4474
|
continue;
|
|
@@ -6424,7 +5364,7 @@ ${r.snippet.trim()}
|
|
|
6424
5364
|
0
|
|
6425
5365
|
);
|
|
6426
5366
|
seedPaths.push(
|
|
6427
|
-
...seedRelativePaths.map((rel) =>
|
|
5367
|
+
...seedRelativePaths.map((rel) => path2.join(storage.dir, rel))
|
|
6428
5368
|
);
|
|
6429
5369
|
const seedSet = new Set(seedRelativePaths);
|
|
6430
5370
|
const expanded = await this.graphIndexFor(storage).spreadingActivation(
|
|
@@ -6435,7 +5375,7 @@ ${r.snippet.trim()}
|
|
|
6435
5375
|
if (expanded.length === 0) continue;
|
|
6436
5376
|
for (const candidate of expanded.slice(0, perNamespaceExpandedCap)) {
|
|
6437
5377
|
if (seedSet.has(candidate.path)) continue;
|
|
6438
|
-
const memoryPath =
|
|
5378
|
+
const memoryPath = path2.resolve(storage.dir, candidate.path);
|
|
6439
5379
|
const memory = await storage.readMemoryByPath(memoryPath);
|
|
6440
5380
|
if (!memory) continue;
|
|
6441
5381
|
if (isArtifactMemoryPath(memory.path)) continue;
|
|
@@ -6459,7 +5399,7 @@ ${r.snippet.trim()}
|
|
|
6459
5399
|
path: memory.path,
|
|
6460
5400
|
score,
|
|
6461
5401
|
namespace,
|
|
6462
|
-
seed:
|
|
5402
|
+
seed: path2.resolve(storage.dir, candidate.seed),
|
|
6463
5403
|
hopDepth: candidate.hopDepth,
|
|
6464
5404
|
decayedWeight: candidate.decayedWeight,
|
|
6465
5405
|
graphType: candidate.graphType,
|
|
@@ -6480,12 +5420,12 @@ ${r.snippet.trim()}
|
|
|
6480
5420
|
}
|
|
6481
5421
|
async recordLastGraphRecallSnapshot(options) {
|
|
6482
5422
|
try {
|
|
6483
|
-
const snapshotPath =
|
|
5423
|
+
const snapshotPath = path2.join(
|
|
6484
5424
|
options.storage.dir,
|
|
6485
5425
|
"state",
|
|
6486
5426
|
"last_graph_recall.json"
|
|
6487
5427
|
);
|
|
6488
|
-
await mkdir2(
|
|
5428
|
+
await mkdir2(path2.dirname(snapshotPath), { recursive: true });
|
|
6489
5429
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
6490
5430
|
const totalSeedCount = options.seedPaths.length;
|
|
6491
5431
|
const totalExpandedCount = options.expandedPaths.length;
|
|
@@ -6519,12 +5459,12 @@ ${r.snippet.trim()}
|
|
|
6519
5459
|
}
|
|
6520
5460
|
async recordLastIntentSnapshot(options) {
|
|
6521
5461
|
try {
|
|
6522
|
-
const snapshotPath =
|
|
5462
|
+
const snapshotPath = path2.join(
|
|
6523
5463
|
options.storage.dir,
|
|
6524
5464
|
"state",
|
|
6525
5465
|
"last_intent.json"
|
|
6526
5466
|
);
|
|
6527
|
-
await mkdir2(
|
|
5467
|
+
await mkdir2(path2.dirname(snapshotPath), { recursive: true });
|
|
6528
5468
|
await writeFile2(
|
|
6529
5469
|
snapshotPath,
|
|
6530
5470
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -6536,12 +5476,12 @@ ${r.snippet.trim()}
|
|
|
6536
5476
|
}
|
|
6537
5477
|
async recordLastQmdRecallSnapshot(options) {
|
|
6538
5478
|
try {
|
|
6539
|
-
const snapshotPath =
|
|
5479
|
+
const snapshotPath = path2.join(
|
|
6540
5480
|
options.storage.dir,
|
|
6541
5481
|
"state",
|
|
6542
5482
|
"last_qmd_recall.json"
|
|
6543
5483
|
);
|
|
6544
|
-
await mkdir2(
|
|
5484
|
+
await mkdir2(path2.dirname(snapshotPath), { recursive: true });
|
|
6545
5485
|
await writeFile2(
|
|
6546
5486
|
snapshotPath,
|
|
6547
5487
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -6556,8 +5496,8 @@ ${r.snippet.trim()}
|
|
|
6556
5496
|
const stateDir = await this.resolveStateDirForNamespace(
|
|
6557
5497
|
options.namespace
|
|
6558
5498
|
);
|
|
6559
|
-
const snapshotPath =
|
|
6560
|
-
await mkdir2(
|
|
5499
|
+
const snapshotPath = path2.join(stateDir, "last_intent.json");
|
|
5500
|
+
await mkdir2(path2.dirname(snapshotPath), { recursive: true });
|
|
6561
5501
|
await writeFile2(
|
|
6562
5502
|
snapshotPath,
|
|
6563
5503
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -6569,12 +5509,12 @@ ${r.snippet.trim()}
|
|
|
6569
5509
|
}
|
|
6570
5510
|
async resolveStateDirForNamespace(namespace) {
|
|
6571
5511
|
if (!this.config.namespacesEnabled) {
|
|
6572
|
-
return
|
|
5512
|
+
return path2.join(this.config.memoryDir, "state");
|
|
6573
5513
|
}
|
|
6574
5514
|
if (namespace !== this.config.defaultNamespace) {
|
|
6575
|
-
return
|
|
5515
|
+
return path2.join(this.config.memoryDir, "namespaces", namespace, "state");
|
|
6576
5516
|
}
|
|
6577
|
-
const candidate =
|
|
5517
|
+
const candidate = path2.join(
|
|
6578
5518
|
this.config.memoryDir,
|
|
6579
5519
|
"namespaces",
|
|
6580
5520
|
this.config.defaultNamespace
|
|
@@ -6582,11 +5522,11 @@ ${r.snippet.trim()}
|
|
|
6582
5522
|
try {
|
|
6583
5523
|
const candidateStat = await stat(candidate);
|
|
6584
5524
|
if (candidateStat.isDirectory()) {
|
|
6585
|
-
return
|
|
5525
|
+
return path2.join(candidate, "state");
|
|
6586
5526
|
}
|
|
6587
5527
|
} catch {
|
|
6588
5528
|
}
|
|
6589
|
-
return
|
|
5529
|
+
return path2.join(this.config.memoryDir, "state");
|
|
6590
5530
|
}
|
|
6591
5531
|
buildGraphRecallRankedResults(results, sourceLabelResolver, limit = 64) {
|
|
6592
5532
|
return results.slice(0, limit).map((result) => ({
|
|
@@ -6972,7 +5912,7 @@ ${r.snippet.trim()}
|
|
|
6972
5912
|
const graphExpandedResultPaths = /* @__PURE__ */ new Set();
|
|
6973
5913
|
const graphSourceLabelsForPath = (resultPath) => {
|
|
6974
5914
|
const labels = [];
|
|
6975
|
-
const normalizedPath = resultPath.split(
|
|
5915
|
+
const normalizedPath = resultPath.split(path2.sep).join("/");
|
|
6976
5916
|
const isEntityPath = normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/");
|
|
6977
5917
|
if (graphBaselinePaths.has(resultPath)) labels.push("baseline");
|
|
6978
5918
|
if (graphExpandedResultPaths.has(resultPath))
|
|
@@ -8287,11 +7227,11 @@ ${formatted}`;
|
|
|
8287
7227
|
if (!this.config.compactionResetEnabled) return null;
|
|
8288
7228
|
const workspaceDir = compactionWorkspaceDir || this.config.workspaceDir || defaultWorkspaceDir();
|
|
8289
7229
|
const safeSessionKey = sanitizeSessionKeyForFilename(effectiveSessionKey);
|
|
8290
|
-
const signalPath =
|
|
7230
|
+
const signalPath = path2.join(
|
|
8291
7231
|
workspaceDir,
|
|
8292
7232
|
`.compaction-reset-signal-${safeSessionKey}`
|
|
8293
7233
|
);
|
|
8294
|
-
const bootPath =
|
|
7234
|
+
const bootPath = path2.join(workspaceDir, "BOOT.md");
|
|
8295
7235
|
try {
|
|
8296
7236
|
const signalStat = await stat(signalPath).catch(() => null);
|
|
8297
7237
|
if (!signalStat) return null;
|
|
@@ -10772,7 +9712,7 @@ ${normalized}`).digest("hex");
|
|
|
10772
9712
|
);
|
|
10773
9713
|
this.tierMigrationInFlight = true;
|
|
10774
9714
|
try {
|
|
10775
|
-
const coldStorage = new StorageManager(
|
|
9715
|
+
const coldStorage = new StorageManager(path2.join(storage.dir, "cold"));
|
|
10776
9716
|
const [hotMemories, coldMemories] = await Promise.all([
|
|
10777
9717
|
storage.readAllMemories(),
|
|
10778
9718
|
coldStorage.readAllMemories()
|
|
@@ -11975,7 +10915,7 @@ ${normalized}`).digest("hex");
|
|
|
11975
10915
|
const allMems = allMemsForGraph ?? [];
|
|
11976
10916
|
for (const m of allMems) {
|
|
11977
10917
|
if (m.frontmatter.entityRef === entityRef) {
|
|
11978
|
-
const rel =
|
|
10918
|
+
const rel = path2.relative(storage.dir, m.path);
|
|
11979
10919
|
if (rel !== memoryRelPath) entitySiblings.push(rel);
|
|
11980
10920
|
}
|
|
11981
10921
|
}
|
|
@@ -12275,7 +11215,7 @@ ${normalized}`).digest("hex");
|
|
|
12275
11215
|
}
|
|
12276
11216
|
if (this.config.semanticConsolidationEnabled) {
|
|
12277
11217
|
try {
|
|
12278
|
-
const stateFilePath =
|
|
11218
|
+
const stateFilePath = path2.join(
|
|
12279
11219
|
this.config.memoryDir,
|
|
12280
11220
|
"state",
|
|
12281
11221
|
"semantic-consolidation-last-run.json"
|
|
@@ -12323,7 +11263,7 @@ ${normalized}`).digest("hex");
|
|
|
12323
11263
|
);
|
|
12324
11264
|
}
|
|
12325
11265
|
if (semResult.errors === 0 || semResult.memoriesArchived > 0) {
|
|
12326
|
-
const stateDir =
|
|
11266
|
+
const stateDir = path2.join(this.config.memoryDir, "state");
|
|
12327
11267
|
await mkdir2(stateDir, { recursive: true });
|
|
12328
11268
|
await writeFile2(
|
|
12329
11269
|
stateFilePath,
|
|
@@ -12818,12 +11758,12 @@ ${texts.map((t, i) => `[${i + 1}] ${t}`).join("\n\n")}`;
|
|
|
12818
11758
|
protectedCategories: this.config.lifecycleProtectedCategories
|
|
12819
11759
|
}
|
|
12820
11760
|
};
|
|
12821
|
-
const metricsPath =
|
|
11761
|
+
const metricsPath = path2.join(
|
|
12822
11762
|
storage.dir,
|
|
12823
11763
|
"state",
|
|
12824
11764
|
"lifecycle-metrics.json"
|
|
12825
11765
|
);
|
|
12826
|
-
await mkdir2(
|
|
11766
|
+
await mkdir2(path2.dirname(metricsPath), { recursive: true });
|
|
12827
11767
|
await writeFile2(metricsPath, JSON.stringify(metrics, null, 2), "utf-8");
|
|
12828
11768
|
}
|
|
12829
11769
|
/**
|
|
@@ -13351,7 +12291,7 @@ ${lines.join("\n\n")}`;
|
|
|
13351
12291
|
nsMap = buildMemoryWorthCounterMap(memories);
|
|
13352
12292
|
this.memoryWorthCounterCache.set(ns, { at: nowMs, counters: nsMap });
|
|
13353
12293
|
}
|
|
13354
|
-
for (const [
|
|
12294
|
+
for (const [path3, c] of nsMap) counters.set(path3, c);
|
|
13355
12295
|
} catch (err) {
|
|
13356
12296
|
log.debug("memory-worth: failed to read namespace, skipping", {
|
|
13357
12297
|
namespace: ns,
|
|
@@ -13522,12 +12462,12 @@ ${lines.join("\n\n")}`;
|
|
|
13522
12462
|
*/
|
|
13523
12463
|
semanticDedupScopeFor(targetStorage) {
|
|
13524
12464
|
if (!this.config.namespacesEnabled) return {};
|
|
13525
|
-
const memoryDir =
|
|
13526
|
-
const storageDir =
|
|
12465
|
+
const memoryDir = path2.resolve(this.config.memoryDir);
|
|
12466
|
+
const storageDir = path2.resolve(targetStorage.dir);
|
|
13527
12467
|
if (storageDir === memoryDir) {
|
|
13528
12468
|
return { pathExcludePrefixes: ["namespaces/"] };
|
|
13529
12469
|
}
|
|
13530
|
-
let rel =
|
|
12470
|
+
let rel = path2.relative(memoryDir, storageDir);
|
|
13531
12471
|
if (!rel || rel.startsWith("..")) {
|
|
13532
12472
|
log.debug(
|
|
13533
12473
|
`semantic dedup: target storage dir ${storageDir} is outside memoryDir ${memoryDir}; scoping lookup to absolute path prefix`
|
|
@@ -13546,7 +12486,7 @@ ${lines.join("\n\n")}`;
|
|
|
13546
12486
|
if (hits.length === 0) return [];
|
|
13547
12487
|
const results = [];
|
|
13548
12488
|
for (const hit of hits) {
|
|
13549
|
-
const fullPath =
|
|
12489
|
+
const fullPath = path2.isAbsolute(hit.path) ? hit.path : path2.join(this.config.memoryDir, hit.path);
|
|
13550
12490
|
const memory = await this.storage.readMemoryByPath(fullPath);
|
|
13551
12491
|
if (!memory) continue;
|
|
13552
12492
|
results.push({
|
|
@@ -14189,8 +13129,8 @@ ${lines.join("\n\n")}`;
|
|
|
14189
13129
|
}
|
|
14190
13130
|
namespaceFromStorageDir(storageDir) {
|
|
14191
13131
|
if (!this.config.namespacesEnabled) return this.config.defaultNamespace;
|
|
14192
|
-
const resolvedStorageDir =
|
|
14193
|
-
const resolvedMemoryDir =
|
|
13132
|
+
const resolvedStorageDir = path2.resolve(storageDir);
|
|
13133
|
+
const resolvedMemoryDir = path2.resolve(this.config.memoryDir);
|
|
14194
13134
|
if (resolvedStorageDir === resolvedMemoryDir)
|
|
14195
13135
|
return this.config.defaultNamespace;
|
|
14196
13136
|
const m = resolvedStorageDir.match(/[\\/]namespaces[\\/]([^\\/]+)$/);
|
|
@@ -14230,27 +13170,6 @@ export {
|
|
|
14230
13170
|
saveTaxonomy,
|
|
14231
13171
|
getTaxonomyDir,
|
|
14232
13172
|
getTaxonomyFilePath,
|
|
14233
|
-
memoryStatusForMode,
|
|
14234
|
-
WEARABLE_SOURCE_PREFIX,
|
|
14235
|
-
wearableSourceLabel,
|
|
14236
|
-
wearableDayTag,
|
|
14237
|
-
buildExtractionTurns,
|
|
14238
|
-
generateWearableMemories,
|
|
14239
|
-
writeDailyDigestMemory,
|
|
14240
|
-
importNativeMemories,
|
|
14241
|
-
cleanConversation,
|
|
14242
|
-
stripFillerTokens,
|
|
14243
|
-
collapseImmediateRepeats,
|
|
14244
|
-
isLowQualitySegment,
|
|
14245
|
-
syncStateFilePath,
|
|
14246
|
-
emptySyncState,
|
|
14247
|
-
loadSyncState,
|
|
14248
|
-
saveSyncState,
|
|
14249
|
-
updateSourceSyncState,
|
|
14250
|
-
dateInTimezone,
|
|
14251
|
-
resolveSyncDates,
|
|
14252
|
-
syncWearableSource,
|
|
14253
|
-
defaultTimezone,
|
|
14254
13173
|
registerWearableConnector,
|
|
14255
13174
|
getWearableConnector,
|
|
14256
13175
|
listWearableConnectors,
|
|
@@ -14287,4 +13206,4 @@ export {
|
|
|
14287
13206
|
resolvePersistedMemoryRelativePath,
|
|
14288
13207
|
Orchestrator
|
|
14289
13208
|
};
|
|
14290
|
-
//# sourceMappingURL=chunk-
|
|
13209
|
+
//# sourceMappingURL=chunk-WLZBVYC6.js.map
|