@jungjaehoon/mama-core 1.9.0 → 2.0.0

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.
Files changed (136) hide show
  1. package/dist/agent-graph/alias-write.js +3 -0
  2. package/dist/agent-graph/entity-resolve.js +3 -7
  3. package/dist/agent-graph/graph-query.js +5 -4
  4. package/dist/agent-graph/types.d.ts +30 -0
  5. package/dist/cases/store.d.ts +0 -4
  6. package/dist/cases/store.js +0 -66
  7. package/dist/cases/wiki-page-index.d.ts +0 -13
  8. package/dist/cases/wiki-page-index.js +0 -153
  9. package/dist/connectors/event-index.d.ts +1 -22
  10. package/dist/connectors/event-index.js +0 -157
  11. package/dist/context-compile/channel-grant.d.ts +46 -0
  12. package/dist/context-compile/channel-grant.js +66 -0
  13. package/dist/context-compile/compiler.js +5 -2
  14. package/dist/context-compile/index.d.ts +1 -0
  15. package/dist/context-compile/index.js +1 -0
  16. package/dist/context-compile/packet-store.d.ts +0 -1
  17. package/dist/context-compile/packet-store.js +0 -16
  18. package/dist/context-compile/source-readers.d.ts +1 -0
  19. package/dist/context-compile/source-readers.js +156 -23
  20. package/dist/context-compile/types.d.ts +17 -0
  21. package/dist/context-compile/visibility.js +28 -4
  22. package/dist/db-adapter/node-sqlite-adapter.js +4 -0
  23. package/dist/db-manager.d.ts +0 -13
  24. package/dist/db-manager.js +0 -66
  25. package/dist/decision-formatter.d.ts +0 -11
  26. package/dist/decision-formatter.js +0 -122
  27. package/dist/decision-tracker.d.ts +0 -12
  28. package/dist/decision-tracker.js +0 -50
  29. package/dist/edges/ref-validation.d.ts +1 -2
  30. package/dist/edges/ref-validation.js +33 -13
  31. package/dist/edges/store.d.ts +1 -3
  32. package/dist/edges/store.js +0 -214
  33. package/dist/edges/types.d.ts +10 -0
  34. package/dist/embedding-client.d.ts +0 -17
  35. package/dist/embedding-client.js +0 -80
  36. package/dist/embedding-server/mobile/auth.d.ts +1 -10
  37. package/dist/embedding-server/mobile/auth.js +0 -15
  38. package/dist/embeddings.d.ts +0 -12
  39. package/dist/embeddings.js +0 -68
  40. package/dist/entities/audit-metrics.d.ts +0 -5
  41. package/dist/entities/audit-metrics.js +0 -4
  42. package/dist/entities/candidate-generator.d.ts +1 -2
  43. package/dist/entities/candidate-generator.js +0 -412
  44. package/dist/entities/entity-list.d.ts +0 -1
  45. package/dist/entities/entity-list.js +0 -96
  46. package/dist/entities/entity-orphan-list.d.ts +0 -9
  47. package/dist/entities/entity-orphan-list.js +0 -88
  48. package/dist/entities/entity-search.d.ts +0 -1
  49. package/dist/entities/entity-search.js +0 -147
  50. package/dist/entities/errors.d.ts +0 -10
  51. package/dist/entities/errors.js +1 -25
  52. package/dist/entities/lineage-store.d.ts +0 -23
  53. package/dist/entities/lineage-store.js +0 -104
  54. package/dist/entities/policy-store.d.ts +0 -9
  55. package/dist/entities/policy-store.js +0 -188
  56. package/dist/entities/provenance-query.d.ts +0 -1
  57. package/dist/entities/provenance-query.js +0 -164
  58. package/dist/entities/resolution-engine.d.ts +1 -8
  59. package/dist/entities/resolution-engine.js +0 -66
  60. package/dist/entities/rollback-preview.d.ts +0 -4
  61. package/dist/entities/rollback-preview.js +0 -232
  62. package/dist/entities/store.d.ts +1 -10
  63. package/dist/entities/store.js +0 -49
  64. package/dist/index.d.ts +15 -31
  65. package/dist/index.js +4 -46
  66. package/dist/mama-api.d.ts +19 -1
  67. package/dist/mama-api.js +97 -2
  68. package/dist/memory/api.d.ts +8 -0
  69. package/dist/memory/api.js +55 -2
  70. package/dist/memory/event-store.d.ts +0 -1
  71. package/dist/memory/event-store.js +0 -15
  72. package/dist/memory/finding-store.d.ts +0 -1
  73. package/dist/memory/finding-store.js +0 -12
  74. package/dist/memory/scope-backfill.d.ts +0 -3
  75. package/dist/memory/scope-backfill.js +0 -74
  76. package/dist/memory/scope-store.d.ts +0 -1
  77. package/dist/memory/scope-store.js +0 -4
  78. package/dist/memory/truth-store.d.ts +0 -3
  79. package/dist/memory/truth-store.js +0 -22
  80. package/dist/memory/types.d.ts +0 -1
  81. package/dist/memory/types.js +0 -13
  82. package/dist/memory-store.d.ts +0 -16
  83. package/dist/memory-store.js +0 -51
  84. package/dist/ollama-client.d.ts +0 -9
  85. package/dist/ollama-client.js +0 -125
  86. package/dist/outcome-tracker.d.ts +0 -14
  87. package/dist/outcome-tracker.js +0 -44
  88. package/dist/progress-indicator.d.ts +0 -4
  89. package/dist/progress-indicator.js +0 -7
  90. package/dist/provenance/source-ref.d.ts +0 -9
  91. package/dist/provenance/source-ref.js +0 -145
  92. package/dist/query-intent.d.ts +0 -4
  93. package/dist/query-intent.js +0 -30
  94. package/dist/relevance-scorer.d.ts +0 -9
  95. package/dist/relevance-scorer.js +0 -81
  96. package/dist/search/feedback-store.d.ts +0 -1
  97. package/dist/search/feedback-store.js +0 -4
  98. package/dist/search/ranker-rescore.d.ts +0 -3
  99. package/dist/search/ranker-rescore.js +0 -27
  100. package/dist/search/ranker-trainer.d.ts +0 -8
  101. package/dist/search/ranker-trainer.js +0 -376
  102. package/dist/tier-validator.d.ts +0 -12
  103. package/dist/tier-validator.js +0 -56
  104. package/package.json +1 -10
  105. package/dist/cases/case-links.d.ts +0 -116
  106. package/dist/cases/case-links.js +0 -794
  107. package/dist/cases/composition-overrides.d.ts +0 -90
  108. package/dist/cases/composition-overrides.js +0 -724
  109. package/dist/cases/corrections.d.ts +0 -156
  110. package/dist/cases/corrections.js +0 -1045
  111. package/dist/cases/freshness.d.ts +0 -57
  112. package/dist/cases/freshness.js +0 -283
  113. package/dist/cases/live-state.d.ts +0 -48
  114. package/dist/cases/live-state.js +0 -256
  115. package/dist/cases/membership-explain.d.ts +0 -56
  116. package/dist/cases/membership-explain.js +0 -140
  117. package/dist/cases/membership-matcher.d.ts +0 -23
  118. package/dist/cases/membership-matcher.js +0 -193
  119. package/dist/cases/merge-split.d.ts +0 -61
  120. package/dist/cases/merge-split.js +0 -368
  121. package/dist/cases/role-inference.d.ts +0 -10
  122. package/dist/cases/role-inference.js +0 -85
  123. package/dist/cases/sqlite-transaction.d.ts +0 -10
  124. package/dist/cases/sqlite-transaction.js +0 -62
  125. package/dist/cases/target-ref.d.ts +0 -25
  126. package/dist/cases/target-ref.js +0 -22
  127. package/dist/cases/tombstone-sweeper.d.ts +0 -13
  128. package/dist/cases/tombstone-sweeper.js +0 -128
  129. package/dist/entities/entity-impact.d.ts +0 -41
  130. package/dist/entities/entity-impact.js +0 -140
  131. package/dist/entities/exact-merge-backfill.d.ts +0 -11
  132. package/dist/entities/exact-merge-backfill.js +0 -161
  133. package/dist/entities/lineage-backfill.d.ts +0 -12
  134. package/dist/entities/lineage-backfill.js +0 -101
  135. package/dist/memory-inject.d.ts +0 -24
  136. package/dist/memory-inject.js +0 -116
@@ -1,29 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.featureSetVersion = exports.SEARCH_RANKER_FEATURE_SET_VERSION = exports.RANKER_QUALITY_FIXTURES = void 0;
4
- exports.trainOfflineRanker = trainOfflineRanker;
5
4
  exports.scoreWithRankerModel = scoreWithRankerModel;
6
- exports.evaluateAgainstBaselines = evaluateAgainstBaselines;
7
- exports.insertRankerModelVersion = insertRankerModelVersion;
8
- exports.activateRankerModel = activateRankerModel;
9
5
  exports.ndcgAtK = ndcgAtK;
10
6
  exports.mrr = mrr;
11
- exports.seedQualityFixtureFeedback = seedQualityFixtureFeedback;
12
- const node_crypto_1 = require("node:crypto");
13
- const feedback_store_js_1 = require("./feedback-store.js");
14
7
  const ranker_features_js_1 = require("./ranker-features.js");
15
8
  Object.defineProperty(exports, "featureSetVersion", { enumerable: true, get: function () { return ranker_features_js_1.featureSetVersion; } });
16
9
  Object.defineProperty(exports, "SEARCH_RANKER_FEATURE_SET_VERSION", { enumerable: true, get: function () { return ranker_features_js_1.SEARCH_RANKER_FEATURE_SET_VERSION; } });
17
- const question_type_js_1 = require("./question-type.js");
18
- const MS_PER_DAY = 24 * 60 * 60 * 1000;
19
- const LEARNING_RATE = 0.05;
20
- const MINI_BATCH_SIZE = 32;
21
- const MAX_EPOCHS = 500;
22
- const EARLY_STOP_DELTA = 1e-5;
23
- const MIN_NEUTRAL_PER_QUERY = 3;
24
10
  // 0.01 is a small but meaningful margin across 8 fixture queries: it blocks
25
11
  // tie/noise wins without demanding a large jump on a tiny evaluation set.
26
- const RANKER_QUALITY_MARGIN = 0.01;
27
12
  function seededShuffle(items, seed) {
28
13
  const shuffled = [...items];
29
14
  let state = seed >>> 0;
@@ -457,105 +442,6 @@ exports.RANKER_QUALITY_FIXTURES = RAW_RANKER_QUALITY_FIXTURES.map((fixture) => (
457
442
  ...fixture,
458
443
  candidates: reorderFixtureCandidates(fixture.query, fixture.candidates),
459
444
  }));
460
- function asSourceForFeedback(sourceType) {
461
- switch (sourceType) {
462
- case 'wiki_page':
463
- return 'wiki_page';
464
- case 'case':
465
- return 'case';
466
- case 'connector_event':
467
- return 'connector_event';
468
- case 'checkpoint':
469
- return 'checkpoint';
470
- default:
471
- return 'decision';
472
- }
473
- }
474
- function parseDate(input, field) {
475
- const date = new Date(input);
476
- if (Number.isNaN(date.getTime())) {
477
- throw new Error(`${field} must be a valid ISO timestamp`);
478
- }
479
- return date;
480
- }
481
- function iso(date) {
482
- return date.toISOString();
483
- }
484
- function effectiveWindow(input) {
485
- const retentionDays = (0, feedback_store_js_1.getFeedbackRetentionDays)(input.adapter);
486
- const now = input.now ?? new Date();
487
- const retentionCutoff = new Date(now.getTime() - retentionDays * MS_PER_DAY);
488
- const until = input.until ? parseDate(input.until, 'until') : now;
489
- const since = input.since ? parseDate(input.since, 'since') : retentionCutoff;
490
- if (since.getTime() > until.getTime()) {
491
- throw new Error('since must be before until');
492
- }
493
- const retentionWarning = Boolean(input.since && since.getTime() < retentionCutoff.getTime());
494
- if (retentionWarning) {
495
- console.warn(JSON.stringify({
496
- event: 'training_window_exceeds_retention',
497
- since: iso(since),
498
- retention_cutoff_at: iso(retentionCutoff),
499
- }));
500
- }
501
- return {
502
- since: iso(since),
503
- until: iso(until),
504
- retention_cutoff_at: iso(retentionCutoff),
505
- retention_days_at_train_time: retentionDays,
506
- retention_warning: retentionWarning,
507
- };
508
- }
509
- function labelForKind(kind) {
510
- if (kind === 'accept' || kind === 'click') {
511
- return 1;
512
- }
513
- if (kind === 'reject' || kind === 'hide' || kind === 'shown') {
514
- return 0;
515
- }
516
- return null;
517
- }
518
- function rowToExample(row) {
519
- const label = labelForKind(row.feedback_kind);
520
- if (label === null) {
521
- return null;
522
- }
523
- const features = (0, ranker_features_js_1.serializeFeatures)((0, ranker_features_js_1.extractFeatures)({
524
- ...row,
525
- source_type: row.result_source_type,
526
- rank_position: row.rank_position,
527
- }, row.query, { question_type: row.question_type }));
528
- return {
529
- query: row.query,
530
- question_type: row.question_type,
531
- features,
532
- label,
533
- feedback_kind: row.feedback_kind,
534
- created_at: row.created_at,
535
- feedback_id: row.feedback_id,
536
- };
537
- }
538
- function capNeutralRows(rows) {
539
- const byQuery = new Map();
540
- for (const row of rows) {
541
- const key = row.query_hash_hex || row.query;
542
- const current = byQuery.get(key) ?? [];
543
- current.push(row);
544
- byQuery.set(key, current);
545
- }
546
- const capped = [];
547
- for (const groupRows of byQuery.values()) {
548
- const explicit = groupRows.filter((row) => row.feedback_kind !== 'shown');
549
- const shown = groupRows.filter((row) => row.feedback_kind === 'shown');
550
- const neutralLimit = Math.max(explicit.length * 3, MIN_NEUTRAL_PER_QUERY);
551
- capped.push(...explicit, ...shown.slice(0, neutralLimit));
552
- }
553
- capped.sort((left, right) => {
554
- const byCreatedAt = left.created_at.localeCompare(right.created_at);
555
- return byCreatedAt !== 0 ? byCreatedAt : left.feedback_id.localeCompare(right.feedback_id);
556
- });
557
- return capped;
558
- }
559
445
  function sigmoid(value) {
560
446
  if (value >= 35) {
561
447
  return 1;
@@ -573,254 +459,11 @@ function dot(left, right) {
573
459
  }
574
460
  return total;
575
461
  }
576
- function hasBothLabels(examples) {
577
- const labels = new Set(examples.map((example) => example.label));
578
- return labels.has(0) && labels.has(1);
579
- }
580
- function trainWeights(examples, featureCount) {
581
- const coefficients = new Array(featureCount).fill(0);
582
- let intercept = 0;
583
- if (examples.length === 0 || !hasBothLabels(examples)) {
584
- return { coefficients, intercept };
585
- }
586
- for (let epoch = 0; epoch < MAX_EPOCHS; epoch += 1) {
587
- const shuffledExamples = seededShuffle(examples, epoch + 1);
588
- let epochDelta = 0;
589
- let batchCount = 0;
590
- for (let batchStart = 0; batchStart < shuffledExamples.length; batchStart += MINI_BATCH_SIZE) {
591
- const batch = shuffledExamples.slice(batchStart, batchStart + MINI_BATCH_SIZE);
592
- const gradients = new Array(featureCount).fill(0);
593
- let interceptGradient = 0;
594
- for (const example of batch) {
595
- const prediction = sigmoid(dot(coefficients, example.features) + intercept);
596
- const error = prediction - example.label;
597
- for (let index = 0; index < featureCount; index += 1) {
598
- gradients[index] += error * example.features[index];
599
- }
600
- interceptGradient += error;
601
- }
602
- let delta = 0;
603
- for (let index = 0; index < featureCount; index += 1) {
604
- const update = (LEARNING_RATE * gradients[index]) / batch.length;
605
- coefficients[index] -= update;
606
- delta += Math.abs(update);
607
- }
608
- const interceptUpdate = (LEARNING_RATE * interceptGradient) / batch.length;
609
- intercept -= interceptUpdate;
610
- delta += Math.abs(interceptUpdate);
611
- epochDelta += delta;
612
- batchCount += 1;
613
- }
614
- if (batchCount > 0 && epochDelta / batchCount < EARLY_STOP_DELTA) {
615
- break;
616
- }
617
- }
618
- return { coefficients, intercept };
619
- }
620
- function questionWeights(examples, featureCount, fallback) {
621
- const output = {};
622
- for (const questionType of question_type_js_1.QUESTION_TYPES) {
623
- const subset = examples.filter((example) => example.question_type === questionType);
624
- output[questionType] = hasBothLabels(subset)
625
- ? trainWeights(subset, featureCount).coefficients
626
- : [...fallback];
627
- }
628
- return output;
629
- }
630
- function modelIdFor(input) {
631
- const compactTime = input.trainedAt.replace(/[^0-9]/g, '').slice(0, 17);
632
- const uniqueSuffix = (0, node_crypto_1.randomBytes)(4).toString('hex');
633
- return `ranker_${compactTime}_${input.rows}_${input.distinctQueries}_${uniqueSuffix}`;
634
- }
635
- async function trainOfflineRanker(input) {
636
- const minFeedbackRows = input.minFeedbackRows ?? 1000;
637
- const minDistinctQueries = input.minDistinctQueries ?? 10;
638
- const window = effectiveWindow(input);
639
- const rows = (0, feedback_store_js_1.listSearchFeedback)(input.adapter, {
640
- since: window.since,
641
- until: window.until,
642
- });
643
- const cappedRows = capNeutralRows(rows);
644
- const examples = cappedRows
645
- .map(rowToExample)
646
- .filter((example) => Boolean(example));
647
- const distinctQueries = new Set(examples.map((example) => example.query.trim().toLowerCase()))
648
- .size;
649
- const counts = {
650
- feedbackRows: examples.length,
651
- distinctQueries,
652
- };
653
- const examplesHaveBothLabels = hasBothLabels(examples);
654
- if (counts.feedbackRows < minFeedbackRows ||
655
- counts.distinctQueries < minDistinctQueries ||
656
- !examplesHaveBothLabels) {
657
- return {
658
- status: 'insufficient_data',
659
- effectiveWindow: window,
660
- counts,
661
- };
662
- }
663
- const featureCount = examples[0].features.length;
664
- const trained = trainWeights(examples, featureCount);
665
- const trainedAt = input.now ? input.now.toISOString() : new Date().toISOString();
666
- const model = {
667
- model_id: modelIdFor({
668
- trainedAt,
669
- rows: counts.feedbackRows,
670
- distinctQueries: counts.distinctQueries,
671
- }),
672
- feature_set_version: input.featureSetVersion ?? (0, ranker_features_js_1.featureSetVersion)(),
673
- trained_at: trainedAt,
674
- training_rows_count: examples.length,
675
- coefficients: trained.coefficients,
676
- intercept: trained.intercept,
677
- question_type_weights: questionWeights(examples, featureCount, trained.coefficients),
678
- training_window: window,
679
- };
680
- return {
681
- status: 'trained',
682
- model,
683
- effectiveWindow: window,
684
- counts,
685
- };
686
- }
687
- function rankByScore(items, score) {
688
- return items
689
- .map((item) => ({ item, score: score(item) }))
690
- .sort((left, right) => {
691
- const diff = right.score - left.score;
692
- if (Math.abs(diff) > 1e-12) {
693
- return diff;
694
- }
695
- return left.item.id.localeCompare(right.item.id);
696
- })
697
- .map((entry) => entry.item);
698
- }
699
- function reciprocalRankRanks(items, leftScore, rightScore) {
700
- const left = rankByScore(items, leftScore);
701
- const right = rankByScore(items, rightScore);
702
- const leftRanks = new Map(left.map((item, index) => [item.id, index + 1]));
703
- const rightRanks = new Map(right.map((item, index) => [item.id, index + 1]));
704
- return rankByScore(items, (item) => {
705
- const leftRank = leftRanks.get(item.id) ?? items.length;
706
- const rightRank = rightRanks.get(item.id) ?? items.length;
707
- return 1 / (60 + leftRank) + 1 / (60 + rightRank);
708
- });
709
- }
710
462
  function scoreWithRankerModel(model, row, query, questionType) {
711
463
  const features = (0, ranker_features_js_1.serializeFeatures)((0, ranker_features_js_1.extractFeatures)(row, query, { question_type: questionType }));
712
464
  const coefficients = model.question_type_weights[questionType] ?? model.coefficients;
713
465
  return sigmoid(dot(coefficients, features) + model.intercept);
714
466
  }
715
- function baselineMetrics(fixtures, ranker) {
716
- const perQuery = {};
717
- let ndcgTotal = 0;
718
- let mrrTotal = 0;
719
- for (const fixture of fixtures) {
720
- const ranked = ranker(fixture);
721
- const relevance = new Map(fixture.candidates.map((candidate) => [candidate.id, candidate.relevance]));
722
- const relevantSet = new Set(fixture.candidates
723
- .filter((candidate) => candidate.relevance > 0)
724
- .map((candidate) => candidate.id));
725
- const ndcg = ndcgAtK(ranked, relevance, 5);
726
- const mrrScore = mrr(ranked, relevantSet);
727
- perQuery[fixture.query] = { ndcg, mrr: mrrScore };
728
- ndcgTotal += ndcg;
729
- mrrTotal += mrrScore;
730
- }
731
- return {
732
- ndcg: ndcgTotal / fixtures.length,
733
- mrr: mrrTotal / fixtures.length,
734
- per_query: perQuery,
735
- };
736
- }
737
- async function evaluateAgainstBaselines(_input, model) {
738
- const bm25 = baselineMetrics(exports.RANKER_QUALITY_FIXTURES, (fixture) => rankByScore(fixture.candidates, (candidate) => candidate.bm25_score));
739
- const vector = baselineMetrics(exports.RANKER_QUALITY_FIXTURES, (fixture) => rankByScore(fixture.candidates, (candidate) => candidate.vector_score));
740
- const rrf = baselineMetrics(exports.RANKER_QUALITY_FIXTURES, (fixture) => reciprocalRankRanks(fixture.candidates, (candidate) => candidate.bm25_score, (candidate) => candidate.vector_score));
741
- const logistic = baselineMetrics(exports.RANKER_QUALITY_FIXTURES, (fixture) => rankByScore(fixture.candidates, (candidate) => 0.5 * candidate.bm25_score + 0.5 * candidate.vector_score));
742
- const learned = baselineMetrics(exports.RANKER_QUALITY_FIXTURES, (fixture) => rankByScore(fixture.candidates, (candidate) => scoreWithRankerModel(model, candidate, fixture.query, fixture.question_type)));
743
- const bestBaselineNdcg = Math.max(bm25.ndcg, vector.ndcg, rrf.ndcg, logistic.ndcg);
744
- const bestBaselineMrr = Math.max(bm25.mrr, vector.mrr, rrf.mrr, logistic.mrr);
745
- return {
746
- bm25,
747
- vector,
748
- rrf,
749
- logistic,
750
- learned,
751
- passes: learned.ndcg >= bestBaselineNdcg + RANKER_QUALITY_MARGIN &&
752
- learned.mrr >= bestBaselineMrr + RANKER_QUALITY_MARGIN,
753
- };
754
- }
755
- function runTransaction(adapter, fn) {
756
- if (!adapter.transaction) {
757
- return fn();
758
- }
759
- const result = adapter.transaction(fn);
760
- if (typeof result === 'function') {
761
- return result();
762
- }
763
- return result;
764
- }
765
- async function insertRankerModelVersion(adapter, model, evaluation) {
766
- const coefficientsPayload = JSON.stringify({
767
- coefficients: model.coefficients,
768
- intercept: model.intercept,
769
- question_type_weights: model.question_type_weights,
770
- training_rows_count: model.training_rows_count,
771
- });
772
- const metricsPayload = JSON.stringify({
773
- learned: evaluation.learned,
774
- passes: evaluation.passes,
775
- });
776
- const baselinePayload = JSON.stringify({
777
- bm25: evaluation.bm25,
778
- vector: evaluation.vector,
779
- rrf: evaluation.rrf,
780
- logistic: evaluation.logistic,
781
- });
782
- const trainingWindowPayload = JSON.stringify(model.training_window ?? {
783
- since: null,
784
- until: null,
785
- retention_cutoff_at: null,
786
- retention_days_at_train_time: null,
787
- retention_warning: false,
788
- });
789
- adapter
790
- .prepare(`
791
- INSERT INTO ranker_model_versions (
792
- model_id, model_version, feature_set_version, coefficients_json, metrics_json,
793
- training_window_json, baseline_metrics_json, quality_gate_status, trained_at,
794
- trained_by, active
795
- )
796
- VALUES (?, 'offline-logistic-v1', ?, ?, ?, ?, ?, ?, ?, 'mama train-ranker', 0)
797
- `)
798
- .run(model.model_id, model.feature_set_version, coefficientsPayload, metricsPayload, trainingWindowPayload, baselinePayload, evaluation.passes ? 'passed' : 'failed', model.trained_at);
799
- return { model_id: model.model_id, active: false };
800
- }
801
- async function activateRankerModel(adapter, model_id) {
802
- const row = adapter
803
- .prepare(`
804
- SELECT model_id, feature_set_version, quality_gate_status
805
- FROM ranker_model_versions
806
- WHERE model_id = ?
807
- `)
808
- .get(model_id);
809
- if (!row) {
810
- return 'not_found';
811
- }
812
- if (row.feature_set_version !== ranker_features_js_1.SEARCH_RANKER_FEATURE_SET_VERSION) {
813
- return 'feature_set_mismatch';
814
- }
815
- if (row.quality_gate_status !== 'passed') {
816
- return 'quality_gate_failed';
817
- }
818
- runTransaction(adapter, () => {
819
- adapter.prepare('UPDATE ranker_model_versions SET active = 0 WHERE active = 1').run();
820
- adapter.prepare('UPDATE ranker_model_versions SET active = 1 WHERE model_id = ?').run(model_id);
821
- });
822
- return 'activated';
823
- }
824
467
  function ndcgAtK(results, relevanceMap, k) {
825
468
  const gains = results.slice(0, k).map((result, index) => {
826
469
  const relevance = relevanceMap.get(result.id) ?? 0;
@@ -838,23 +481,4 @@ function mrr(results, relevantSet) {
838
481
  const index = results.findIndex((result) => relevantSet.has(result.id));
839
482
  return index === -1 ? 0 : 1 / (index + 1);
840
483
  }
841
- function seedQualityFixtureFeedback(adapter, createdAt = '2026-04-18T00:00:00.000Z') {
842
- let counter = 0;
843
- for (const fixture of exports.RANKER_QUALITY_FIXTURES) {
844
- for (const candidate of fixture.candidates) {
845
- counter += 1;
846
- const kind = candidate.relevance >= 3 ? 'accept' : 'reject';
847
- adapter
848
- .prepare(`
849
- INSERT INTO search_feedback (
850
- feedback_id, query, query_hash, question_type, result_source_type, result_source_id,
851
- case_id, feedback_kind, rank_position, score_before, score_after, session_id,
852
- actor, metadata_json, created_at, updated_at
853
- )
854
- VALUES (?, ?, zeroblob(32), ?, ?, ?, NULL, ?, ?, NULL, NULL, ?, 'test:ranker-fixture', '{}', ?, NULL)
855
- `)
856
- .run(`quality-${counter}`, fixture.query, fixture.question_type, asSourceForFeedback(candidate.source_type), candidate.id, kind, counter % 5, `fixture:${fixture.question_type}`, createdAt);
857
- }
858
- }
859
- }
860
484
  //# sourceMappingURL=ranker-trainer.js.map
@@ -36,20 +36,8 @@ export declare function checkEmbeddings(): CheckResult;
36
36
  * Validates database file accessibility
37
37
  */
38
38
  export declare function checkDatabase(): CheckResult;
39
- /**
40
- * Validates MAMA tier status
41
- *
42
- * Performs all system checks and determines tier:
43
- * - Tier 1: All checks pass (full features)
44
- * - Tier 2: One or more checks fail (degraded mode)
45
- */
46
- export declare function validateTier(): Promise<TierValidation>;
47
39
  /**
48
40
  * Get user-friendly tier description
49
41
  */
50
42
  export declare function getTierDescription(tier: number): string;
51
- /**
52
- * Get tier status banner
53
- */
54
- export declare function getTierBanner(validation: TierValidation): string;
55
43
  //# sourceMappingURL=tier-validator.d.ts.map
@@ -18,9 +18,7 @@ exports.checkNodeVersion = checkNodeVersion;
18
18
  exports.checkSQLite = checkSQLite;
19
19
  exports.checkEmbeddings = checkEmbeddings;
20
20
  exports.checkDatabase = checkDatabase;
21
- exports.validateTier = validateTier;
22
21
  exports.getTierDescription = getTierDescription;
23
- exports.getTierBanner = getTierBanner;
24
22
  const fs_1 = __importDefault(require("fs"));
25
23
  const path_1 = __importDefault(require("path"));
26
24
  const os_1 = __importDefault(require("os"));
@@ -148,39 +146,6 @@ function checkDatabase() {
148
146
  };
149
147
  }
150
148
  }
151
- /**
152
- * Validates MAMA tier status
153
- *
154
- * Performs all system checks and determines tier:
155
- * - Tier 1: All checks pass (full features)
156
- * - Tier 2: One or more checks fail (degraded mode)
157
- */
158
- async function validateTier() {
159
- const checks = [
160
- {
161
- name: 'Node.js',
162
- ...checkNodeVersion(),
163
- },
164
- {
165
- name: 'SQLite',
166
- ...checkSQLite(),
167
- },
168
- {
169
- name: 'Embeddings',
170
- ...checkEmbeddings(),
171
- },
172
- {
173
- name: 'Database',
174
- ...checkDatabase(),
175
- },
176
- ];
177
- // Determine tier: all pass = tier 1, any fail = tier 2
178
- const tier = checks.every((c) => c.status === 'pass') ? 1 : 2;
179
- return {
180
- tier,
181
- checks,
182
- };
183
- }
184
149
  /**
185
150
  * Get user-friendly tier description
186
151
  */
@@ -191,25 +156,4 @@ function getTierDescription(tier) {
191
156
  };
192
157
  return descriptions[tier] || 'Unknown Tier';
193
158
  }
194
- /**
195
- * Get tier status banner
196
- */
197
- function getTierBanner(validation) {
198
- const { tier, checks } = validation;
199
- const failedChecks = checks.filter((c) => c.status === 'fail');
200
- let banner = `\n┌─────────────────────────────────────────┐\n`;
201
- banner += `│ MAMA Tier ${tier}: ${getTierDescription(tier).split(' - ')[0]}\n`;
202
- if (failedChecks.length > 0) {
203
- banner += `│\n`;
204
- banner += `│ ⚠️ Issues detected:\n`;
205
- failedChecks.forEach((check) => {
206
- banner += `│ • ${check.name}: ${check.details}\n`;
207
- });
208
- }
209
- else {
210
- banner += `│ ✅ All systems operational\n`;
211
- }
212
- banner += `└─────────────────────────────────────────┘\n`;
213
- return banner;
214
- }
215
159
  //# sourceMappingURL=tier-validator.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jungjaehoon/mama-core",
3
- "version": "1.9.0",
3
+ "version": "2.0.0",
4
4
  "description": "MAMA Core - Shared modules for Memory-Augmented MCP Assistant",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -20,7 +20,6 @@
20
20
  "./decision-tracker": "./dist/decision-tracker.js",
21
21
  "./debug-logger": "./dist/debug-logger.js",
22
22
  "./decision-formatter": "./dist/decision-formatter.js",
23
- "./memory-inject": "./dist/memory-inject.js",
24
23
  "./ollama-client": "./dist/ollama-client.js",
25
24
  "./errors": "./dist/errors.js",
26
25
  "./time-formatter": "./dist/time-formatter.js",
@@ -32,14 +31,6 @@
32
31
  "./canonicalize": "./dist/canonicalize.js",
33
32
  "./cases/types": "./dist/cases/types.js",
34
33
  "./cases/store": "./dist/cases/store.js",
35
- "./cases/role-inference": "./dist/cases/role-inference.js",
36
- "./cases/target-ref": "./dist/cases/target-ref.js",
37
- "./cases/corrections": "./dist/cases/corrections.js",
38
- "./cases/sqlite-transaction": "./dist/cases/sqlite-transaction.js",
39
- "./cases/live-state": "./dist/cases/live-state.js",
40
- "./cases/tombstone-sweeper": "./dist/cases/tombstone-sweeper.js",
41
- "./cases/merge-split": "./dist/cases/merge-split.js",
42
- "./cases/membership-matcher": "./dist/cases/membership-matcher.js",
43
34
  "./cases/search-rollup": "./dist/cases/search-rollup.js",
44
35
  "./cases/timeline-range": "./dist/cases/timeline-range.js",
45
36
  "./cases/wiki-page-index": "./dist/cases/wiki-page-index.js",
@@ -1,116 +0,0 @@
1
- import type { DatabaseAdapter } from '../db-manager.js';
2
- import { type ImmediateTransactionAdapter } from './sqlite-transaction.js';
3
- export type CaseLinkType = 'related' | 'supersedes-case' | 'subcase-of' | 'blocked-by' | 'duplicate-of';
4
- export type CaseLinkSourceKind = 'manual' | 'wiki_compiler' | 'hitl_correction' | 'system_backfill';
5
- export interface CaseLinkRecord {
6
- link_id: string;
7
- case_id_from: string;
8
- case_id_to: string;
9
- link_type: CaseLinkType;
10
- created_at: string;
11
- created_by: string;
12
- confidence: number | null;
13
- reason_json: string | null;
14
- source_kind: CaseLinkSourceKind;
15
- source_ref: string | null;
16
- source_ref_fingerprint: Buffer | null;
17
- source_ref_fingerprint_hex: string | null;
18
- revoked_at: string | null;
19
- revoked_by: string | null;
20
- revoke_reason: string | null;
21
- }
22
- export interface CaseLinkCreateInput {
23
- link_id?: string;
24
- case_id_from: string;
25
- case_id_to: string;
26
- link_type: CaseLinkType;
27
- created_by: string;
28
- confidence?: number | null;
29
- reason_json?: string | Record<string, unknown> | null;
30
- source_kind?: CaseLinkSourceKind;
31
- source_ref?: string | null;
32
- source_ref_fingerprint?: Buffer | Uint8Array | null;
33
- unsuppress_wiki_tombstone?: boolean;
34
- expected_current_value_json?: string | null;
35
- reconfirm_token?: string | null;
36
- session_id?: string | null;
37
- now?: string;
38
- }
39
- export interface CaseLinkRevokeInput {
40
- link_id: string;
41
- revoked_by: string;
42
- revoke_reason: string;
43
- expected_current_value_json?: string | null;
44
- reconfirm_token?: string | null;
45
- session_id?: string | null;
46
- now?: string;
47
- }
48
- export interface CaseLinkRequiresReconfirmResult {
49
- kind: 'requires_reconfirm';
50
- code: 'case.correction_requires_reconfirm';
51
- case_id: string;
52
- target_kind: 'case_link';
53
- target_ref_json: string;
54
- current_value_json: string;
55
- old_value_json: string | null;
56
- proposed_new_value_json: string;
57
- reconfirm_token: string;
58
- reconfirm_token_expires_at: string;
59
- message: string;
60
- }
61
- export type CaseLinkCreateResult = {
62
- kind: 'created';
63
- link_id: string;
64
- source_ref_fingerprint_hex: string;
65
- } | CaseLinkRequiresReconfirmResult | {
66
- kind: 'rejected';
67
- code: 'case.precompile_gap' | 'case.terminal_status' | 'case.self_link' | 'case.wiki_tombstone_conflict' | 'case.correction_active_conflict' | 'case.reconfirm_token_replayed';
68
- message: string;
69
- case_id?: string;
70
- };
71
- export type CaseLinkRevokeResult = {
72
- kind: 'revoked';
73
- link_id: string;
74
- } | CaseLinkRequiresReconfirmResult | {
75
- kind: 'rejected';
76
- code: 'case.case_link_not_found' | 'case.wiki_tombstone_fingerprint_missing' | 'case.reconfirm_token_replayed';
77
- message: string;
78
- link_id?: string;
79
- };
80
- export interface ListActiveCaseLinksResult {
81
- terminal_case_id: string;
82
- resolved_via_case_id: string | null;
83
- chain: string[];
84
- links: CaseLinkRecord[];
85
- }
86
- export interface BackfillStructuralLinksResult {
87
- duplicate_of_inserted: number;
88
- subcase_of_inserted: number;
89
- }
90
- type CaseLinkAdapter = Pick<DatabaseAdapter, 'prepare' | 'transaction'> & Partial<Pick<ImmediateTransactionAdapter, 'exec'>>;
91
- export declare function sha256TombstoneFingerprint(input: {
92
- source_case_id: string;
93
- target_case_id: string;
94
- link_type: CaseLinkType;
95
- }): Buffer;
96
- export declare function createCaseLink(adapter: DatabaseAdapter, input: CaseLinkCreateInput): CaseLinkCreateResult;
97
- export declare function revokeCaseLink(adapter: DatabaseAdapter, input: CaseLinkRevokeInput): CaseLinkRevokeResult;
98
- export declare function listActiveCaseLinks(adapter: DatabaseAdapter, caseId: string): ListActiveCaseLinksResult;
99
- export declare function isWikiTombstoneActive(adapter: DatabaseAdapter | CaseLinkAdapter, input: {
100
- source_case_id: string;
101
- target_case_id: string;
102
- link_type: CaseLinkType;
103
- }): boolean;
104
- export declare function unsuppressWikiTombstone(adapter: DatabaseAdapter, input: {
105
- source_case_id: string;
106
- target_case_id: string;
107
- link_type: CaseLinkType;
108
- unsuppressed_by: string;
109
- now?: string;
110
- }): {
111
- kind: 'unsuppressed';
112
- unsuppressed_count: number;
113
- };
114
- export declare function backfillStructuralLinks(adapter: DatabaseAdapter): BackfillStructuralLinksResult;
115
- export {};
116
- //# sourceMappingURL=case-links.d.ts.map