memorix 0.11.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -10611,6 +10611,205 @@ var init_project_affinity = __esm({
10611
10611
  }
10612
10612
  });
10613
10613
 
10614
+ // src/search/intent-detector.ts
10615
+ function detectQueryIntent(query) {
10616
+ if (!query || query.length < 2) {
10617
+ return {
10618
+ intent: "general",
10619
+ confidence: 0,
10620
+ typeBoosts: {},
10621
+ preferChronological: false
10622
+ };
10623
+ }
10624
+ let bestIntent = "general";
10625
+ let bestScore = 0;
10626
+ let totalMatches = 0;
10627
+ for (const { intent, patterns, weight } of INTENT_PATTERNS) {
10628
+ let matchCount = 0;
10629
+ for (const pattern of patterns) {
10630
+ if (pattern.test(query)) matchCount++;
10631
+ }
10632
+ if (matchCount > 0) {
10633
+ const score = matchCount * weight;
10634
+ totalMatches += matchCount;
10635
+ if (score > bestScore) {
10636
+ bestScore = score;
10637
+ bestIntent = intent;
10638
+ }
10639
+ }
10640
+ }
10641
+ const confidence = totalMatches === 0 ? 0 : Math.min(1, bestScore / 2);
10642
+ return {
10643
+ intent: bestIntent,
10644
+ confidence,
10645
+ typeBoosts: INTENT_TYPE_BOOSTS[bestIntent],
10646
+ fieldBoosts: INTENT_FIELD_BOOSTS[bestIntent],
10647
+ preferChronological: bestIntent === "when"
10648
+ };
10649
+ }
10650
+ function applyIntentBoost(score, type, intentResult) {
10651
+ if (intentResult.confidence < 0.3) return score;
10652
+ const boost = intentResult.typeBoosts[type] ?? 1;
10653
+ const effectiveBoost = 1 + (boost - 1) * intentResult.confidence;
10654
+ return score * effectiveBoost;
10655
+ }
10656
+ var INTENT_PATTERNS, INTENT_TYPE_BOOSTS, INTENT_FIELD_BOOSTS;
10657
+ var init_intent_detector = __esm({
10658
+ "src/search/intent-detector.ts"() {
10659
+ "use strict";
10660
+ init_esm_shims();
10661
+ INTENT_PATTERNS = [
10662
+ {
10663
+ intent: "why",
10664
+ patterns: [
10665
+ /\bwhy\b/i,
10666
+ /\breason(?:s|ing)?\b/i,
10667
+ /\brationale\b/i,
10668
+ /\bmotivat(?:ion|ed)\b/i,
10669
+ /\bjustif(?:y|ication)\b/i,
10670
+ /\bchose|chosen|picked\b/i,
10671
+ /\bdecid(?:e[ds]?|ing)\b/i,
10672
+ /\btrade-?off\b/i,
10673
+ /为什么/,
10674
+ /原因/,
10675
+ /理由/,
10676
+ /为何/
10677
+ ],
10678
+ weight: 1
10679
+ },
10680
+ {
10681
+ intent: "when",
10682
+ patterns: [
10683
+ /\bwhen\b/i,
10684
+ /\btimeline\b/i,
10685
+ /\bhistory\b/i,
10686
+ /\blast\s+(week|month|time|session)\b/i,
10687
+ /\brecent(?:ly)?\b/i,
10688
+ /\byesterday\b/i,
10689
+ /\btoday\b/i,
10690
+ /\bchronolog/i,
10691
+ /什么时候/,
10692
+ /何时/,
10693
+ /最近/,
10694
+ /上次/
10695
+ ],
10696
+ weight: 0.9
10697
+ },
10698
+ {
10699
+ intent: "how",
10700
+ patterns: [
10701
+ /\bhow\s+(does|do|to|is|can|did|should|would)\b/i,
10702
+ /\barchitecture\b/i,
10703
+ /\bmechanism\b/i,
10704
+ /\bimplement(?:ation|ed|ing)?\b/i,
10705
+ /\bwork(?:s|ing|ed)?\b/i,
10706
+ /\bexplain\b/i,
10707
+ /\bunderstand\b/i,
10708
+ /怎么/,
10709
+ /如何/,
10710
+ /机制/,
10711
+ /原理/,
10712
+ /架构/
10713
+ ],
10714
+ weight: 0.85
10715
+ },
10716
+ {
10717
+ intent: "what_changed",
10718
+ patterns: [
10719
+ /\bwhat\s+changed\b/i,
10720
+ /\bwhat\s+was\s+(modified|updated|changed)\b/i,
10721
+ /\bdiff(?:erence)?\b/i,
10722
+ /\bchangelog\b/i,
10723
+ /\bmodifi(?:ed|cation)\b/i,
10724
+ /\bupdat(?:e[ds]?|ing)\b/i,
10725
+ /\brefactor(?:ed|ing)?\b/i,
10726
+ /改了/,
10727
+ /修改/,
10728
+ /变更/,
10729
+ /变化/
10730
+ ],
10731
+ weight: 0.8
10732
+ },
10733
+ {
10734
+ intent: "problem",
10735
+ patterns: [
10736
+ /\bbug(?:s|gy)?\b/i,
10737
+ /\berror(?:s)?\b/i,
10738
+ /\bfix(?:e[ds]|ing)?\b/i,
10739
+ /\bissue(?:s)?\b/i,
10740
+ /\bproblem(?:s)?\b/i,
10741
+ /\bcrash(?:e[ds]|ing)?\b/i,
10742
+ /\bfail(?:e[ds]|ure|ing)?\b/i,
10743
+ /\bbroken\b/i,
10744
+ /\bgotcha\b/i,
10745
+ /\bpitfall\b/i,
10746
+ /\bworkaround\b/i,
10747
+ /\btroubleshoot/i,
10748
+ /\bdebug(?:ging)?\b/i,
10749
+ /报错/,
10750
+ /问题/,
10751
+ /修复/,
10752
+ /故障/,
10753
+ /异常/
10754
+ ],
10755
+ weight: 0.9
10756
+ }
10757
+ ];
10758
+ INTENT_TYPE_BOOSTS = {
10759
+ why: {
10760
+ "decision": 3,
10761
+ "why-it-exists": 3,
10762
+ "trade-off": 2.5,
10763
+ "how-it-works": 1.2
10764
+ },
10765
+ when: {
10766
+ // Temporal queries don't strongly prefer any type — they prefer recency
10767
+ "what-changed": 1.5,
10768
+ "session-request": 1.3
10769
+ },
10770
+ how: {
10771
+ "how-it-works": 3,
10772
+ "discovery": 2,
10773
+ "decision": 1.3
10774
+ },
10775
+ what_changed: {
10776
+ "what-changed": 3,
10777
+ "discovery": 1.5,
10778
+ "session-request": 1.2
10779
+ },
10780
+ problem: {
10781
+ "problem-solution": 3,
10782
+ "gotcha": 2.5,
10783
+ "discovery": 1.3
10784
+ },
10785
+ general: {
10786
+ // No special boosting
10787
+ }
10788
+ };
10789
+ INTENT_FIELD_BOOSTS = {
10790
+ why: {
10791
+ title: 2,
10792
+ entityName: 1.5,
10793
+ narrative: 2.5,
10794
+ // WHY queries need narrative context
10795
+ facts: 1.5,
10796
+ concepts: 1,
10797
+ filesModified: 0.3
10798
+ },
10799
+ problem: {
10800
+ title: 3,
10801
+ entityName: 2,
10802
+ narrative: 2,
10803
+ facts: 2,
10804
+ // Bug details often in facts
10805
+ concepts: 1,
10806
+ filesModified: 1.5
10807
+ // File paths help find the right bug fix
10808
+ }
10809
+ };
10810
+ }
10811
+ });
10812
+
10614
10813
  // src/project/aliases.ts
10615
10814
  var aliases_exports = {};
10616
10815
  __export(aliases_exports, {
@@ -13913,22 +14112,25 @@ async function searchObservations(options2) {
13913
14112
  filters["type"] = options2.type;
13914
14113
  }
13915
14114
  const hasQuery = options2.query && options2.query.trim().length > 0;
14115
+ const intentResult = hasQuery ? detectQueryIntent(options2.query) : null;
13916
14116
  const requestLimit = projectIds && projectIds.length > 1 ? (options2.limit ?? 20) * 3 : options2.limit ?? 20;
14117
+ const defaultBoost = {
14118
+ title: 3,
14119
+ entityName: 2,
14120
+ concepts: 1.5,
14121
+ narrative: 1,
14122
+ facts: 1,
14123
+ filesModified: 0.5
14124
+ };
14125
+ const fieldBoost = (intentResult?.confidence ?? 0) > 0.3 && intentResult?.fieldBoosts ? intentResult.fieldBoosts : defaultBoost;
13917
14126
  let searchParams = {
13918
14127
  term: options2.query,
13919
14128
  limit: requestLimit,
13920
14129
  ...Object.keys(filters).length > 0 ? { where: filters } : {},
13921
14130
  // Search specific fields (not tokens, accessCount, etc.)
13922
14131
  properties: ["title", "entityName", "narrative", "facts", "concepts", "filesModified"],
13923
- // Field boosting: title and entity matches rank higher
13924
- boost: {
13925
- title: 3,
13926
- entityName: 2,
13927
- concepts: 1.5,
13928
- narrative: 1,
13929
- facts: 1,
13930
- filesModified: 0.5
13931
- },
14132
+ // Field boosting: intent-aware or default
14133
+ boost: fieldBoost,
13932
14134
  // Fuzzy tolerance: allow 1-char typos for short queries, 2 for longer
13933
14135
  ...hasQuery ? { tolerance: options2.query.length > 6 ? 2 : 1 } : {}
13934
14136
  };
@@ -14002,7 +14204,17 @@ async function searchObservations(options2) {
14002
14204
  score: (hit.score ?? 1) * recencyBoost
14003
14205
  };
14004
14206
  });
14005
- intermediate.sort((a3, b3) => b3.score - a3.score);
14207
+ if (intentResult && intentResult.confidence > 0.3) {
14208
+ intermediate = intermediate.map((entry) => ({
14209
+ ...entry,
14210
+ score: applyIntentBoost(entry.score, entry.type, intentResult)
14211
+ }));
14212
+ }
14213
+ if (intentResult?.preferChronological) {
14214
+ intermediate.sort((a3, b3) => new Date(b3.rawTime).getTime() - new Date(a3.rawTime).getTime());
14215
+ } else {
14216
+ intermediate.sort((a3, b3) => b3.score - a3.score);
14217
+ }
14006
14218
  if (options2.projectId && intermediate.length > 0) {
14007
14219
  const projectName = options2.projectId.split("/").pop() ?? options2.projectId;
14008
14220
  const affinityContext = {
@@ -14209,6 +14421,7 @@ var init_orama_store = __esm({
14209
14421
  init_types2();
14210
14422
  init_provider();
14211
14423
  init_project_affinity();
14424
+ init_intent_detector();
14212
14425
  db = null;
14213
14426
  embeddingEnabled = false;
14214
14427
  }