@futdevpro/fdp-agent-memory 1.1.112 → 1.1.115

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@futdevpro/fdp-agent-memory",
3
- "version": "1.1.112",
3
+ "version": "1.1.115",
4
4
  "description": "Local-first, vector-backed multi-table agent memory exposed as an MCP server (read/write/capabilities). Public, FDP-Templates-free, no auth.",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -140,6 +140,18 @@ exports.CONFIG_CATALOG = {
140
140
  + 'A tiszta-szemantikus találat (lexical 0) SOHA nem süllyed (×1). READ-time (nincs re-embed). `0` = pure-vektor '
141
141
  + '(régi viselkedés). Default 0.6.',
142
142
  },
143
+ 'read.scanSummaryWeight': {
144
+ type: 'number', default: 1.0, min: 0.0, max: 10.0, levels: ALL_LEVELS,
145
+ description: 'A `source.type:"scan-summary"` (auto-generált projekt-összefoglaló: `project-identity` + '
146
+ + '`fs-summary`) chunkok EFFEKTÍV statikus weight-SAPKÁJA read-időben (2026-07-26 dispatch-eval): e '
147
+ + 'generikus entry-k `weight:3` (project-identity) / `weight:2` (fs-summary) → `finalScore ~2.2` még '
148
+ + 'lexicalScore 0-0.2 mellett is elnyomta a szemantikailag+lexikailag relevánsabb doksikat. E cap a '
149
+ + 'scan-summary effektív weight-jét `min(weight, scanSummaryWeight)`-re szorítja (factor = cap/weight), '
150
+ + 'hogy a STATIKUS weight NE tudja legyőzni a relevanciát. `1.0` = tiszta relevancia-rangsor (nincs statikus '
151
+ + 'boost); az identity-jellegű query-ken a summary a MAGAS cosine-ja miatt így is felszínre kerül (nincs '
152
+ + 'regresszió). READ-time (nincs re-embed); a nyers cosine + a `weight` DTO-mező NEM változik, csak a ranking. '
153
+ + 'A stored weight ALÁ csökkenteni is lehet (<1) az agresszívabb leszorításhoz; ≥ stored weight = kikapcsolva.',
154
+ },
143
155
  'read.denseResultRatio': {
144
156
  type: 'number', default: 2.0, min: 1.0, max: 50.0, levels: ALL_LEVELS,
145
157
  description: 'Dense-jelzés ratio-kapuja: totalRelevant >= ratio*topK → denseResults (dsgn-005 §4.2).',
@@ -393,6 +405,38 @@ exports.CONFIG_CATALOG = {
393
405
  + '(pl. mindig ugyanazon a tartalmon összeomló) job nem indul újra a végtelenségig minden restartkor. `0` = '
394
406
  + 'soha ne resume-olj automatikusan.',
395
407
  },
408
+ // --- 4.5b. Weekly auto full re-scan + delete-sync (fogyasztó: FAM_ScanScheduler_ControlService) ---
409
+ 'scan.weeklyRescanEnabled': {
410
+ type: 'boolean', default: true, levels: GLOBAL_ONLY,
411
+ description: 'Heti automatikus TELJES FAM re-scan + törlés-szinkron (reconcile/delta) be/ki (2026-07-26). A meglévő '
412
+ + 'reconcile-logika (a scan orphan-soft-delete-eli a lemezről eltűnt fájlok chunkjait) HETI ütemezéssel fut, hogy '
413
+ + 'a FAM-tartalom naprakész maradjon. A cél a `scan.weeklyRescanRoot` (ha üres → a LEGUTÓBBI durable scan-job '
414
+ + 'cél-specjeit re-scanneli). Best-effort, in-process (nincs külső cron). `false` → nincs heti auto-re-scan.',
415
+ },
416
+ 'scan.weeklyRescanDayOfWeek': {
417
+ type: 'number', default: 1, min: 0, max: 6, integer: true, levels: GLOBAL_ONLY,
418
+ description: 'A heti re-scan napja (LOKÁLIS idő): `0`=vasárnap … `1`=hétfő (default) … `6`=szombat. A slot a '
419
+ + '`scan.weeklyRescanHour` órán. Ha a szerver a slot-időben nem futott (down), a következő indításkor BEPÓTOLJA '
420
+ + '(catch-up: a legutóbbi elmúlt slot óta nem futott → most fut).',
421
+ },
422
+ 'scan.weeklyRescanHour': {
423
+ type: 'number', default: 7, min: 0, max: 23, integer: true, levels: GLOBAL_ONLY,
424
+ description: 'A heti re-scan órája (LOKÁLIS idő, 0-23; default `7` = 07:00). A `scan.weeklyRescanDayOfWeek` napján ez '
425
+ + 'az óra:00 a heti slot.',
426
+ },
427
+ 'scan.weeklyRescanRoot': {
428
+ type: 'string', default: '', levels: GLOBAL_ONLY,
429
+ description: 'A heti re-scan gyökere (abszolút út). Ha megadva → e root alatt felderített projektek re-scanje '
430
+ + '(reconcile-lel). Ha ÜRES (default) → a LEGUTÓBBI durable scan-job cél-specjeit re-scanneli (zero-config '
431
+ + 'freshness). Ha egyik sincs (üres + nincs korábbi scan) → a heti futás SKIP + egyszeri warn (nincs találgatás).',
432
+ },
433
+ 'scan.weeklyRescanLastRunAt': {
434
+ type: 'number', default: 0, min: 0, max: 9999999999999, integer: true, levels: GLOBAL_ONLY,
435
+ description: 'ÁLLAPOT/observability (NEM felhasználói hangoló): a legutóbbi heti re-scan TRIGGER epoch-ms-e. A '
436
+ + 'scheduler ezzel dönti el, hogy egy heti slot óta futott-e már (idempotencia + catch-up + restart-storm '
437
+ + 'elleni védelem). `0` = még sosem futott. A scheduler írja; kézzel ne állítsd (a `fam config get`-tel '
438
+ + 'olvasható, mikor futott utoljára).',
439
+ },
396
440
  // --- 4.6. Reference / scope (fogyasztó: dsgn-002) ---
397
441
  'reference.cacheTtlMs': {
398
442
  type: 'number', default: 60000, min: 0, max: 3600000, integer: true, levels: GLOBAL_ONLY,
@@ -7,6 +7,7 @@ const fam_hydration_coordinator_control_service_1 = require("./fam-hydration-coo
7
7
  const fam_vector_search_control_service_1 = require("./fam-vector-search.control-service");
8
8
  const fam_scope_maintenance_control_service_1 = require("../../scope-reference/_services/fam-scope-maintenance.control-service");
9
9
  const fam_scan_job_control_service_1 = require("../../ingest/_services/fam-scan-job.control-service");
10
+ const fam_scan_scheduler_control_service_1 = require("../../ingest/_services/fam-scan-scheduler.control-service");
10
11
  const fam_memory_dormancy_control_service_1 = require("../../retrieval/_services/fam-memory-dormancy.control-service");
11
12
  /**
12
13
  * `FAM_EmbeddingBootstrap_ControlService` (SP-2.2/2.4) — az embedding + vektor-réteg **boot-hook**-ja.
@@ -97,6 +98,15 @@ class FAM_EmbeddingBootstrap_ControlService {
97
98
  catch (error) {
98
99
  fsm_dynamo_1.DyFM_Log.warn(`[FAM bootstrap] memory-dormancy sweep sikertelen: ${error?.message}`);
99
100
  }
101
+ // HETI AUTO RE-SCAN + DELETE-SYNC (dispatch „Problem 2", 2026-07-26): az in-process ütemező telepítése — a heti
102
+ // slotot (default hétfő 07:00) figyeli + boot-catch-up-ol. A reconcile-logika már létezik; ez csak az ütemezés.
103
+ // Best-effort (a telepítés hibája nem buktatja a bootot; a scheduler maga is best-effort végig).
104
+ try {
105
+ fam_scan_scheduler_control_service_1.FAM_ScanScheduler_ControlService.getInstance().install();
106
+ }
107
+ catch (error) {
108
+ fsm_dynamo_1.DyFM_Log.warn(`[FAM bootstrap] heti re-scan scheduler telepítése sikertelen: ${error?.message}`);
109
+ }
100
110
  }
101
111
  }
102
112
  exports.FAM_EmbeddingBootstrap_ControlService = FAM_EmbeddingBootstrap_ControlService;
@@ -30,5 +30,21 @@ class FAM_ScanJob_DataService extends nts_dynamo_1.DyNTS_DataService {
30
30
  async findResumable() {
31
31
  return this.findDataList({ status: { $in: ['running', 'pending'] } }, true);
32
32
  }
33
+ /**
34
+ * A LEGUTÓBB indított durable scan-job feloldott cél-specjei (weekly re-scan auto-derive, 2026-07-26): a `startedAt`
35
+ * szerint csökkenő rendben az ELSŐ job, amelynek nem-üres `specs`-e van. Így a heti re-scan zero-config újra-futtatja
36
+ * PONTOSAN a legutóbb szkennelt cél-halmazt (per-projekt path/scope/table), amikor nincs explicit `scan.weeklyRescanRoot`.
37
+ * `undefined`, ha még sosem volt cél-speces scan.
38
+ */
39
+ async findLatestScannedTargets() {
40
+ const found = await this.searchData({ sortBy: [{ key: 'startedAt', order: -1 }], pageSize: 25 });
41
+ for (const job of found.results ?? []) {
42
+ const specs = job.specs;
43
+ if (specs && specs.length) {
44
+ return specs;
45
+ }
46
+ }
47
+ return undefined;
48
+ }
33
49
  }
34
50
  exports.FAM_ScanJob_DataService = FAM_ScanJob_DataService;
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FAM_ScanScheduler_ControlService = void 0;
4
+ const fsm_dynamo_1 = require("@futdevpro/fsm-dynamo");
5
+ const fam_config_level_type_enum_1 = require("../../../_enums/fam-config-level.type-enum");
6
+ const config_control_service_1 = require("../../../_routes/server/config/config.control-service");
7
+ const fam_scan_job_control_service_1 = require("./fam-scan-job.control-service");
8
+ const fam_scan_job_data_service_1 = require("./fam-scan-job.data-service");
9
+ /**
10
+ * `FAM_ScanScheduler_ControlService` (2026-07-26, dispatch „Problem 2") — a HETI automatikus TELJES FAM re-scan +
11
+ * törlés-szinkron (reconcile/delta) IN-PROCESS ütemezője. A reconcile-logika MÁR LÉTEZIK (a scan orphan-soft-delete-eli
12
+ * a lemezről eltűnt fájlok chunkjait, dsgn `scan.reconcileIgnored`); ez a service CSAK az ÜTEMEZÉST adja hozzá, hogy a
13
+ * FAM-tartalom naprakész maradjon anélkül, hogy manuálisan re-scannelni kellene.
14
+ *
15
+ * **Slot:** LOKÁLIS idő `scan.weeklyRescanDayOfWeek` (default 1 = hétfő) @ `scan.weeklyRescanHour`:00 (default 7 → 07:00).
16
+ * **Catch-up:** egy fix időközű tick (10 perc) figyeli, hogy a LEGUTÓBBI elmúlt slot óta futott-e már (`scan.weeklyRescanLastRunAt`).
17
+ * Ha a szerver a slot-időben nem futott (down/restart), a következő indításkor BEPÓTOL — a heti freshness így restart-tűrő.
18
+ * **Restart-storm ellen:** a `lastRunAt` a config-store-ban perzisztál → egy héten belüli restart NEM indít újabb re-scant.
19
+ * **Cél:** `scan.weeklyRescanRoot` (ha megadva) VAGY a legutóbbi durable scan-job cél-specjei (zero-config). Egyik sincs → SKIP + warn.
20
+ * Best-effort végig (a hibák logolódnak, a szerver-start/futás NEM bukik el).
21
+ */
22
+ class FAM_ScanScheduler_ControlService {
23
+ static _instance;
24
+ issuer = 'FAM_ScanScheduler_ControlService';
25
+ timer;
26
+ ticking = false;
27
+ /** A slot-ellenőrzés fix pollozási időköze (ms) — 10 perc. NEM a heti slot; csak „megnéztük-e már, hogy due-e". */
28
+ static CHECK_INTERVAL_MS = 600000;
29
+ static getInstance() {
30
+ if (!FAM_ScanScheduler_ControlService._instance) {
31
+ FAM_ScanScheduler_ControlService._instance = new FAM_ScanScheduler_ControlService();
32
+ }
33
+ return FAM_ScanScheduler_ControlService._instance;
34
+ }
35
+ /** Teszt-reset (a singleton + a timer ürítése). */
36
+ static resetForTest() {
37
+ FAM_ScanScheduler_ControlService._instance?.uninstall();
38
+ FAM_ScanScheduler_ControlService._instance = undefined;
39
+ }
40
+ /**
41
+ * A boot() best-effort hívja: beállít egy periodikus tick-et (CHECK_INTERVAL_MS), ami a heti slotot figyeli, majd
42
+ * AZONNAL futtat egy első tick-et (boot-catch-up: ha a legutóbbi slot már elmúlt és nem futott, most bepótol).
43
+ * Idempotens (kétszeri install → egy timer). A timer `unref`-elt (nem tartja életben a processt önmagában).
44
+ */
45
+ install() {
46
+ if (this.timer) {
47
+ return;
48
+ }
49
+ this.timer = setInterval(() => { void this.tick(Date.now()); }, FAM_ScanScheduler_ControlService.CHECK_INTERVAL_MS);
50
+ if (typeof this.timer.unref === 'function') {
51
+ this.timer.unref();
52
+ }
53
+ fsm_dynamo_1.DyFM_Log.info(`[FAM scanScheduler] heti re-scan figyelő telepítve (tick ${FAM_ScanScheduler_ControlService.CHECK_INTERVAL_MS / 60000} percenként).`);
54
+ void this.tick(Date.now());
55
+ }
56
+ /** A timer leállítása (teszt / graceful). */
57
+ uninstall() {
58
+ if (this.timer) {
59
+ clearInterval(this.timer);
60
+ this.timer = undefined;
61
+ }
62
+ }
63
+ /**
64
+ * Egy ellenőrzési ciklus: DUE-e a heti slot? Ha igen → rögzíti a `lastRunAt`-ot (idempotencia + restart-storm ellen),
65
+ * majd elindítja a re-scant. Best-effort (nem dob). Re-entráns-védett (`ticking`), hogy egy lassú tick ne fedjen át
66
+ * a következővel.
67
+ */
68
+ async tick(nowMs) {
69
+ if (this.ticking) {
70
+ return;
71
+ }
72
+ this.ticking = true;
73
+ try {
74
+ const config = config_control_service_1.FAM_Config_ControlService.getInstance();
75
+ const enabled = (await config.resolve('scan.weeklyRescanEnabled')).value;
76
+ if (enabled === false) {
77
+ return;
78
+ }
79
+ const day = await this.resolveNum(config, 'scan.weeklyRescanDayOfWeek', 1);
80
+ const hour = await this.resolveNum(config, 'scan.weeklyRescanHour', 7);
81
+ const lastRun = await this.resolveNum(config, 'scan.weeklyRescanLastRunAt', 0);
82
+ const slot = FAM_ScanScheduler_ControlService.mostRecentSlotAtOrBefore(nowMs, day, hour);
83
+ if (lastRun >= slot) {
84
+ return; // e heti slot óta már futott (vagy még nem jött el a slot)
85
+ }
86
+ // DUE: ELŐBB rögzítjük a lastRun-t (így egy crash mid-scan sem indít újra minden restartkor; a heti freshness
87
+ // best-effort, nem exactly-once), MAJD indítjuk a scant.
88
+ await this.markRan(config, nowMs);
89
+ await this.triggerRescan();
90
+ }
91
+ catch (error) {
92
+ fsm_dynamo_1.DyFM_Log.warn(`[FAM scanScheduler] heti re-scan tick sikertelen (best-effort): ${error?.message}`);
93
+ }
94
+ finally {
95
+ this.ticking = false;
96
+ }
97
+ }
98
+ /** A TELJES re-scan indítása: `scan.weeklyRescanRoot` (ha van) VAGY a legutóbbi durable scan-job cél-specjei. */
99
+ async triggerRescan() {
100
+ const origin = { agent: 'fam-scheduler', label: 'weekly-rescan' };
101
+ const config = config_control_service_1.FAM_Config_ControlService.getInstance();
102
+ const rootValue = (await config.resolve('scan.weeklyRescanRoot')).value;
103
+ const root = typeof rootValue === 'string' ? rootValue.trim() : '';
104
+ if (root) {
105
+ await fam_scan_job_control_service_1.FAM_ScanJob_ControlService.getInstance().start({ root: root, sourceLocation: root, origin: origin, waitMs: 0 });
106
+ fsm_dynamo_1.DyFM_Log.info(`[FAM scanScheduler] heti TELJES re-scan + reconcile INDÍTVA (root: ${root}).`);
107
+ return;
108
+ }
109
+ // Zero-config: a legutóbbi durable scan-job feloldott cél-specjei (ugyanaz a cél-halmaz, reconcile-lel).
110
+ const targets = await this.loadLatestScannedTargets();
111
+ if (targets && targets.length) {
112
+ await fam_scan_job_control_service_1.FAM_ScanJob_ControlService.getInstance().start({ projects: targets, origin: origin, waitMs: 0 });
113
+ fsm_dynamo_1.DyFM_Log.info(`[FAM scanScheduler] heti TELJES re-scan + reconcile INDÍTVA (${targets.length} cél a legutóbbi scan-ből).`);
114
+ return;
115
+ }
116
+ fsm_dynamo_1.DyFM_Log.warn('[FAM scanScheduler] heti re-scan esedékes, DE nincs cél: állítsd be a `scan.weeklyRescanRoot`-ot '
117
+ + 'vagy futtass egy scant előbb (durable cél-specek) — most SKIP.');
118
+ }
119
+ /**
120
+ * A legutóbbi durable scan-job feloldott cél-specjei (zero-config re-scan). KÜLÖN metódus, hogy a `DyNTS_DataService`
121
+ * eager DB-resolve-ja (memory: `dynts_dataservice_eager_resolve`) NE példányosítsa a data-service-t a DB-mentes unit
122
+ * tesztekben — a teszt ezt a metódust spy-olja. A tényleges query a `FAM_ScanJob_DataService` specjében fedve.
123
+ */
124
+ async loadLatestScannedTargets() {
125
+ return new fam_scan_job_data_service_1.FAM_ScanJob_DataService({ issuer: this.issuer }).findLatestScannedTargets();
126
+ }
127
+ /** A `lastRunAt` állapot perzisztálása a config-store-ba (global szint). Best-effort. */
128
+ async markRan(config, nowMs) {
129
+ try {
130
+ await config.set('scan.weeklyRescanLastRunAt', nowMs, {
131
+ level: fam_config_level_type_enum_1.FAM_ConfigLevel.global, setBy: 'system', note: 'weekly re-scan trigger',
132
+ });
133
+ }
134
+ catch (error) {
135
+ fsm_dynamo_1.DyFM_Log.warn(`[FAM scanScheduler] lastRunAt perzisztálás sikertelen: ${error?.message}`);
136
+ }
137
+ }
138
+ /** Egy szám-config feloldása a default-tal. */
139
+ async resolveNum(config, key, fallback) {
140
+ const value = (await config.resolve(key)).value;
141
+ return typeof value === 'number' ? value : fallback;
142
+ }
143
+ /**
144
+ * PURE, tesztelhető: a `nowMs`-nál NEM-későbbi legutóbbi (`dayOfWeek` @ `hour`:00) LOKÁLIS-idő slot epoch-ms-e.
145
+ * (a) ma `hour`:00-ra állítja, (b) visszalép a cél-hétköznapra (`getDay()` diff, 0=vasárnap), (c) ha az így kapott
146
+ * slot még a JÖVŐben van (ma a cél-nap, de a `hour` még nem jött el), egy héttel korábbra lép. DST-re best-effort.
147
+ */
148
+ static mostRecentSlotAtOrBefore(nowMs, dayOfWeek, hour) {
149
+ const d = new Date(nowMs);
150
+ d.setHours(hour, 0, 0, 0);
151
+ const dayDiff = (d.getDay() - dayOfWeek + 7) % 7;
152
+ d.setDate(d.getDate() - dayDiff);
153
+ if (d.getTime() > nowMs) {
154
+ d.setDate(d.getDate() - 7);
155
+ }
156
+ return d.getTime();
157
+ }
158
+ }
159
+ exports.FAM_ScanScheduler_ControlService = FAM_ScanScheduler_ControlService;
@@ -398,6 +398,22 @@ class FAM_Retrieval_ControlService {
398
398
  importSourceFactor(source, importSourceWeight) {
399
399
  return source?.type === 'import' ? importSourceWeight : 1;
400
400
  }
401
+ /**
402
+ * Scan-summary read-idejű weight-SAPKA (2026-07-26 dispatch-eval): az auto-generált projekt-összefoglaló
403
+ * (`source.type:'scan-summary'` — EGYSZERRE fedi a `project-identity` weight:3 ÉS az `fs-summary` weight:2
404
+ * entry-ket) statikus weight-boost-ját neutralizálja. Mérve: e generikus chunkok `finalScore ~1.3-2.2`-vel a
405
+ * TOP-hitek lettek OFF-topic query-ken is (lexicalScore 0-0.2), elnyomva a relevánsabb doksikat. A factor a
406
+ * effektív weight-et `min(weight, scanSummaryWeight)`-re szorítja (weight > cap → `cap/weight`, különben ×1),
407
+ * így a STATIKUS weight NEM tudja legyőzni a szemantikai + lexikai relevanciát. `scanSummaryWeight=1.0` (default)
408
+ * → tiszta relevancia-rangsor; az identity-query-ken a summary a MAGAS cosine miatt így is felszínre kerül. Minden
409
+ * NEM-scan-summary source érintetlen (×1). READ-time, a nyers `score` (relevancia) változatlan.
410
+ */
411
+ scanSummaryFactor(source, weight, scanSummaryWeight) {
412
+ if (source?.type !== 'scan-summary' || weight <= scanSummaryWeight) {
413
+ return 1;
414
+ }
415
+ return scanSummaryWeight / weight;
416
+ }
401
417
  /**
402
418
  * Memory Activation Model decay-szorzó (dsgn-013 §3) — CSAK a `memory` táron, ha engedélyezett. A frissen/gyakran
403
419
  * FELIDÉZETT memória felül-, a régóta érintetlen alul-rangsorol, de a `floorWeight > 0` miatt SOSEM esik ki. A
@@ -437,6 +453,7 @@ class FAM_Retrieval_ControlService {
437
453
  // finalScore = score × weight × chunkF × sourceF × decayF × (1 + keywordWeight × lexicalScore).
438
454
  const chunkFactor = this.chunkTypeFactor(set.entry.chunkType, set.importChunkWeight);
439
455
  const sourceFactor = this.importSourceFactor(set.entry.source, set.importSourceWeight);
456
+ const summaryFactor = this.scanSummaryFactor(set.entry.source, set.weight, set.config.scanSummaryWeight);
440
457
  const decayFactor = this.memoryDecayFactor(set.entry, set.table, set.config, set.nowMs);
441
458
  const lexicalScore = set.config.keywordWeight > 0
442
459
  ? fam_lexical_match_util_1.FAM_LexicalMatch_Util.score(set.queryTerms, {
@@ -449,7 +466,7 @@ class FAM_Retrieval_ControlService {
449
466
  table: set.table,
450
467
  score: set.vectorHit.score,
451
468
  weight: set.weight,
452
- finalScore: set.vectorHit.score * set.weight * chunkFactor * sourceFactor * decayFactor * keywordBoost,
469
+ finalScore: set.vectorHit.score * set.weight * chunkFactor * sourceFactor * summaryFactor * decayFactor * keywordBoost,
453
470
  lexicalScore: lexicalScore,
454
471
  content: set.includeContent ? set.entry.content : undefined,
455
472
  contentHash: set.entry.contentHash,
@@ -655,6 +672,7 @@ class FAM_Retrieval_ControlService {
655
672
  const relevanceFloor = await this.resolveNumber(config, 'read.relevanceFloor', ctx, 0.5);
656
673
  const importChunkWeight = await this.resolveNumber(config, 'read.importChunkWeight', ctx, 0.4);
657
674
  const importSourceWeight = await this.resolveNumber(config, 'read.importSourceWeight', ctx, 0.85);
675
+ const scanSummaryWeight = await this.resolveNumber(config, 'read.scanSummaryWeight', ctx, 1.0);
658
676
  const keywordWeight = await this.resolveNumber(config, 'read.keywordWeight', ctx, 0.6);
659
677
  const denseResultRatio = await this.resolveNumber(config, 'read.denseResultRatio', ctx, 2.0);
660
678
  const denseResultAbsMin = await this.resolveNumber(config, 'read.denseResultAbsMin', ctx, 25);
@@ -679,6 +697,7 @@ class FAM_Retrieval_ControlService {
679
697
  relevanceFloor: relevanceFloor,
680
698
  importChunkWeight: importChunkWeight,
681
699
  importSourceWeight: importSourceWeight,
700
+ scanSummaryWeight: scanSummaryWeight,
682
701
  keywordWeight: keywordWeight,
683
702
  denseResultRatio: denseResultRatio,
684
703
  denseResultAbsMin: denseResultAbsMin,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@futdevpro/fdp-agent-memory",
3
- "version": "1.1.112",
3
+ "version": "1.1.115",
4
4
  "description": "Local-first, vector-backed multi-table agent memory exposed as an MCP server (read/write/capabilities). Public, FDP-Templates-free, no auth.",
5
5
  "private": false,
6
6
  "publishConfig": {