@reftrixmcp/ml 0.1.7

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 (97) hide show
  1. package/LICENSE +661 -0
  2. package/dist/dinov2/index.d.ts +7 -0
  3. package/dist/dinov2/index.d.ts.map +1 -0
  4. package/dist/dinov2/index.js +7 -0
  5. package/dist/dinov2/index.js.map +1 -0
  6. package/dist/dinov2/service.d.ts +106 -0
  7. package/dist/dinov2/service.d.ts.map +1 -0
  8. package/dist/dinov2/service.js +446 -0
  9. package/dist/dinov2/service.js.map +1 -0
  10. package/dist/dinov2/worker-thread-types.d.ts +77 -0
  11. package/dist/dinov2/worker-thread-types.d.ts.map +1 -0
  12. package/dist/dinov2/worker-thread-types.js +4 -0
  13. package/dist/dinov2/worker-thread-types.js.map +1 -0
  14. package/dist/dinov2/worker-thread.d.ts +2 -0
  15. package/dist/dinov2/worker-thread.d.ts.map +1 -0
  16. package/dist/dinov2/worker-thread.js +231 -0
  17. package/dist/dinov2/worker-thread.js.map +1 -0
  18. package/dist/embeddings/index.d.ts +12 -0
  19. package/dist/embeddings/index.d.ts.map +1 -0
  20. package/dist/embeddings/index.js +13 -0
  21. package/dist/embeddings/index.js.map +1 -0
  22. package/dist/embeddings/multimodal-embedding.service.d.ts +400 -0
  23. package/dist/embeddings/multimodal-embedding.service.d.ts.map +1 -0
  24. package/dist/embeddings/multimodal-embedding.service.js +650 -0
  25. package/dist/embeddings/multimodal-embedding.service.js.map +1 -0
  26. package/dist/embeddings/service.d.ts +261 -0
  27. package/dist/embeddings/service.d.ts.map +1 -0
  28. package/dist/embeddings/service.js +1093 -0
  29. package/dist/embeddings/service.js.map +1 -0
  30. package/dist/embeddings/style-embedding.service.d.ts +117 -0
  31. package/dist/embeddings/style-embedding.service.d.ts.map +1 -0
  32. package/dist/embeddings/style-embedding.service.js +157 -0
  33. package/dist/embeddings/style-embedding.service.js.map +1 -0
  34. package/dist/embeddings/types.d.ts +83 -0
  35. package/dist/embeddings/types.d.ts.map +1 -0
  36. package/dist/embeddings/types.js +4 -0
  37. package/dist/embeddings/types.js.map +1 -0
  38. package/dist/embeddings/vision-embedding.service.d.ts +70 -0
  39. package/dist/embeddings/vision-embedding.service.d.ts.map +1 -0
  40. package/dist/embeddings/vision-embedding.service.js +221 -0
  41. package/dist/embeddings/vision-embedding.service.js.map +1 -0
  42. package/dist/embeddings/vision-embedding.types.d.ts +102 -0
  43. package/dist/embeddings/vision-embedding.types.d.ts.map +1 -0
  44. package/dist/embeddings/vision-embedding.types.js +4 -0
  45. package/dist/embeddings/vision-embedding.types.js.map +1 -0
  46. package/dist/embeddings/worker-thread-types.d.ts +152 -0
  47. package/dist/embeddings/worker-thread-types.d.ts.map +1 -0
  48. package/dist/embeddings/worker-thread-types.js +4 -0
  49. package/dist/embeddings/worker-thread-types.js.map +1 -0
  50. package/dist/embeddings/worker-thread.d.ts +4 -0
  51. package/dist/embeddings/worker-thread.d.ts.map +1 -0
  52. package/dist/embeddings/worker-thread.js +441 -0
  53. package/dist/embeddings/worker-thread.js.map +1 -0
  54. package/dist/index.d.ts +18 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +19 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/search/fulltext-helpers.d.ts +30 -0
  59. package/dist/search/fulltext-helpers.d.ts.map +1 -0
  60. package/dist/search/fulltext-helpers.js +40 -0
  61. package/dist/search/fulltext-helpers.js.map +1 -0
  62. package/dist/search/hybrid.d.ts +40 -0
  63. package/dist/search/hybrid.d.ts.map +1 -0
  64. package/dist/search/hybrid.js +61 -0
  65. package/dist/search/hybrid.js.map +1 -0
  66. package/dist/search/index.d.ts +12 -0
  67. package/dist/search/index.d.ts.map +1 -0
  68. package/dist/search/index.js +11 -0
  69. package/dist/search/index.js.map +1 -0
  70. package/dist/search/rrf.d.ts +69 -0
  71. package/dist/search/rrf.d.ts.map +1 -0
  72. package/dist/search/rrf.js +108 -0
  73. package/dist/search/rrf.js.map +1 -0
  74. package/dist/search/types.d.ts +130 -0
  75. package/dist/search/types.d.ts.map +1 -0
  76. package/dist/search/types.js +4 -0
  77. package/dist/search/types.js.map +1 -0
  78. package/package.json +65 -0
  79. package/src/dinov2/index.ts +21 -0
  80. package/src/dinov2/service.ts +539 -0
  81. package/src/dinov2/worker-thread-types.ts +103 -0
  82. package/src/dinov2/worker-thread.ts +306 -0
  83. package/src/embeddings/index.ts +74 -0
  84. package/src/embeddings/multimodal-embedding.service.ts +992 -0
  85. package/src/embeddings/service.ts +1287 -0
  86. package/src/embeddings/style-embedding.service.ts +201 -0
  87. package/src/embeddings/types.ts +95 -0
  88. package/src/embeddings/vision-embedding.service.ts +273 -0
  89. package/src/embeddings/vision-embedding.types.ts +117 -0
  90. package/src/embeddings/worker-thread-types.ts +194 -0
  91. package/src/embeddings/worker-thread.ts +529 -0
  92. package/src/index.ts +70 -0
  93. package/src/search/fulltext-helpers.ts +45 -0
  94. package/src/search/hybrid.ts +107 -0
  95. package/src/search/index.ts +25 -0
  96. package/src/search/rrf.ts +154 -0
  97. package/src/search/types.ts +141 -0
@@ -0,0 +1,61 @@
1
+ // SPDX-FileCopyrightText: 2025-2026 Reftrix Contributors
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Hybrid Search Service
5
+ *
6
+ * Combines vector search (pgvector cosine similarity) and full-text search
7
+ * (PostgreSQL tsvector/tsquery) using Reciprocal Rank Fusion (RRF).
8
+ *
9
+ * Default weights: 60% vector + 40% full-text
10
+ */
11
+ import { mergeWithRRF, normalizeRRFScore } from "./rrf.js";
12
+ const DEFAULT_CONFIG = {
13
+ vectorWeight: 0.6,
14
+ fulltextWeight: 0.4,
15
+ k: 60,
16
+ };
17
+ /**
18
+ * Execute hybrid search by combining vector and full-text search results with RRF
19
+ *
20
+ * Both search functions are executed in parallel via Promise.all for minimum latency.
21
+ * Results are merged using Reciprocal Rank Fusion (RRF) with configurable weights.
22
+ *
23
+ * @param vectorSearchFn - Function that returns vector search results (ranked by cosine similarity)
24
+ * @param fulltextSearchFn - Function that returns full-text search results (ranked by ts_rank_cd)
25
+ * @param config - Optional hybrid search configuration
26
+ * @returns Merged results sorted by normalized RRF similarity score
27
+ */
28
+ export async function executeHybridSearch(vectorSearchFn, fulltextSearchFn, config) {
29
+ const { vectorWeight, fulltextWeight, k } = {
30
+ ...DEFAULT_CONFIG,
31
+ ...config,
32
+ };
33
+ // Execute both searches in parallel for minimum latency
34
+ const [vectorResults, fulltextResults] = await Promise.all([
35
+ vectorSearchFn(),
36
+ fulltextSearchFn(),
37
+ ]);
38
+ // If one source returns empty, fall back to the other source only
39
+ if (vectorResults.length === 0 && fulltextResults.length === 0) {
40
+ return [];
41
+ }
42
+ // Merge with RRF
43
+ const merged = mergeWithRRF(vectorResults, fulltextResults, vectorWeight, fulltextWeight, k);
44
+ // Normalize scores and format output
45
+ return merged.map((item) => {
46
+ const source = {};
47
+ if (item.vectorRank !== undefined) {
48
+ source.vectorRank = item.vectorRank;
49
+ }
50
+ if (item.fulltextRank !== undefined) {
51
+ source.fulltextRank = item.fulltextRank;
52
+ }
53
+ return {
54
+ id: item.id,
55
+ similarity: normalizeRRFScore(item.rrfScore),
56
+ source,
57
+ data: item.data,
58
+ };
59
+ });
60
+ }
61
+ //# sourceMappingURL=hybrid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hybrid.js","sourceRoot":"","sources":["../../src/search/hybrid.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,yCAAyC;AAEzC;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AA+B3D,MAAM,cAAc,GAAiC;IACnD,YAAY,EAAE,GAAG;IACjB,cAAc,EAAE,GAAG;IACnB,CAAC,EAAE,EAAE;CACN,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,cAA2C,EAC3C,gBAA6C,EAC7C,MAA2B;IAE3B,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC,EAAE,GAAG;QAC1C,GAAG,cAAc;QACjB,GAAG,MAAM;KACV,CAAC;IAEF,wDAAwD;IACxD,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACzD,cAAc,EAAE;QAChB,gBAAgB,EAAE;KACnB,CAAC,CAAC;IAEH,kEAAkE;IAClE,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/D,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,iBAAiB;IACjB,MAAM,MAAM,GAAoB,YAAY,CAC1C,aAAa,EACb,eAAe,EACf,YAAY,EACZ,cAAc,EACd,CAAC,CACF,CAAC;IAEF,qCAAqC;IACrC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,IAAmB,EAAsB,EAAE;QAC5D,MAAM,MAAM,GAAiC,EAAE,CAAC;QAChD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAClC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QACtC,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QAC1C,CAAC;QACD,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,UAAU,EAAE,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC;YAC5C,MAAM;YACN,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Search utilities exports
3
+ *
4
+ * RRF utilities and types for WebDesign search services.
5
+ */
6
+ export { calculateRRF, mergeWithRRF, normalizeRRFScore, toRankedItems } from "./rrf.js";
7
+ export type { RankedItem, RRFScoredItem } from "./rrf.js";
8
+ export { executeHybridSearch } from "./hybrid.js";
9
+ export { buildFulltextConditions, buildFulltextRankExpression } from "./fulltext-helpers.js";
10
+ export type { HybridSearchConfig, HybridSearchResult } from "./hybrid.js";
11
+ export type { SearchFilters, SearchOptions, HybridSearchOptions, SearchResult, SummarySearchResult, SearchResultItem, SummarySearchResultItem, VectorSearchRawResult, FullTextSearchRawResult, } from "./types.js";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/search/index.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACxF,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AAC7F,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC1E,YAAY,EACV,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,EACvB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,11 @@
1
+ // SPDX-FileCopyrightText: 2026 TKMD and Reftrix Contributors
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Search utilities exports
5
+ *
6
+ * RRF utilities and types for WebDesign search services.
7
+ */
8
+ export { calculateRRF, mergeWithRRF, normalizeRRFScore, toRankedItems } from "./rrf.js";
9
+ export { executeHybridSearch } from "./hybrid.js";
10
+ export { buildFulltextConditions, buildFulltextRankExpression } from "./fulltext-helpers.js";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/search/index.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,yCAAyC;AAEzC;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAExF,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Reciprocal Rank Fusion (RRF) implementation
3
+ *
4
+ * RRF is a method for combining rankings from multiple search sources.
5
+ * It's particularly useful for hybrid search combining vector and full-text results.
6
+ *
7
+ * Formula: score = 1 / (k + rank)
8
+ * where k is a constant (typically 60) that prevents high-ranked items from
9
+ * dominating the final ranking.
10
+ */
11
+ /**
12
+ * Item with ranking information from a single source
13
+ */
14
+ export interface RankedItem {
15
+ id: string;
16
+ rank: number;
17
+ [key: string]: unknown;
18
+ }
19
+ /**
20
+ * Item with combined RRF score
21
+ */
22
+ export interface RRFScoredItem {
23
+ id: string;
24
+ rrfScore: number;
25
+ vectorRank?: number;
26
+ fulltextRank?: number;
27
+ data: Record<string, unknown>;
28
+ }
29
+ /**
30
+ * Calculate RRF score for a single rank position
31
+ *
32
+ * @param rank - Rank position (1-based)
33
+ * @param k - Ranking constant (default 60)
34
+ * @returns RRF score
35
+ */
36
+ export declare function calculateRRF(rank: number, k?: number): number;
37
+ /**
38
+ * Merge results from vector and full-text search using RRF
39
+ *
40
+ * @param vectorResults - Results from vector similarity search
41
+ * @param fulltextResults - Results from full-text search
42
+ * @param vectorWeight - Weight for vector search results (default 0.6)
43
+ * @param fulltextWeight - Weight for full-text search results (default 0.4)
44
+ * @param k - RRF constant (default 60)
45
+ * @returns Merged and sorted results
46
+ */
47
+ export declare function mergeWithRRF(vectorResults: RankedItem[], fulltextResults: RankedItem[], vectorWeight?: number, fulltextWeight?: number, k?: number): RRFScoredItem[];
48
+ /**
49
+ * Convert an array of rows (with an `id` field) into RankedItem[] with 1-based ranks.
50
+ *
51
+ * The array order is preserved and used for rank assignment.
52
+ * All fields from each row are spread into the resulting RankedItem.
53
+ *
54
+ * @param rows - Array of objects that each contain at least an `id: string` field
55
+ * @returns RankedItem[] with rank starting from 1
56
+ */
57
+ export declare function toRankedItems<T extends {
58
+ id: string;
59
+ }>(rows: T[]): RankedItem[];
60
+ /**
61
+ * Calculate effective score from RRF for display purposes
62
+ * Normalizes the RRF score to a 0-1 range
63
+ *
64
+ * @param rrfScore - Raw RRF score
65
+ * @param maxPossibleScore - Maximum possible score (sum of max vector and fulltext scores)
66
+ * @returns Normalized similarity score (0-1)
67
+ */
68
+ export declare function normalizeRRFScore(rrfScore: number, maxPossibleScore?: number): number;
69
+ //# sourceMappingURL=rrf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rrf.d.ts","sourceRoot":"","sources":["../../src/search/rrf.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AAEH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,GAAE,MAAW,GAAG,MAAM,CAEjE;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,aAAa,EAAE,UAAU,EAAE,EAC3B,eAAe,EAAE,UAAU,EAAE,EAC7B,YAAY,GAAE,MAAY,EAC1B,cAAc,GAAE,MAAY,EAC5B,CAAC,GAAE,MAAW,GACb,aAAa,EAAE,CA4DjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,UAAU,EAAE,CAK/E;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAMrF"}
@@ -0,0 +1,108 @@
1
+ // SPDX-FileCopyrightText: 2026 TKMD and Reftrix Contributors
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ /**
4
+ * Calculate RRF score for a single rank position
5
+ *
6
+ * @param rank - Rank position (1-based)
7
+ * @param k - Ranking constant (default 60)
8
+ * @returns RRF score
9
+ */
10
+ export function calculateRRF(rank, k = 60) {
11
+ return 1 / (k + rank);
12
+ }
13
+ /**
14
+ * Merge results from vector and full-text search using RRF
15
+ *
16
+ * @param vectorResults - Results from vector similarity search
17
+ * @param fulltextResults - Results from full-text search
18
+ * @param vectorWeight - Weight for vector search results (default 0.6)
19
+ * @param fulltextWeight - Weight for full-text search results (default 0.4)
20
+ * @param k - RRF constant (default 60)
21
+ * @returns Merged and sorted results
22
+ */
23
+ export function mergeWithRRF(vectorResults, fulltextResults, vectorWeight = 0.6, fulltextWeight = 0.4, k = 60) {
24
+ const scoreMap = new Map();
25
+ // Process vector search results
26
+ vectorResults.forEach((item, index) => {
27
+ const rank = index + 1; // 1-based rank
28
+ const rrfScore = calculateRRF(rank, k) * vectorWeight;
29
+ const existing = scoreMap.get(item.id);
30
+ if (existing) {
31
+ existing.rrfScore += rrfScore;
32
+ existing.vectorRank = rank;
33
+ }
34
+ else {
35
+ const { id: _id, rank: _, ...data } = item;
36
+ scoreMap.set(item.id, {
37
+ id: item.id,
38
+ rrfScore,
39
+ vectorRank: rank,
40
+ data: data,
41
+ });
42
+ }
43
+ });
44
+ // Process full-text search results
45
+ fulltextResults.forEach((item, index) => {
46
+ const rank = index + 1; // 1-based rank
47
+ const rrfScore = calculateRRF(rank, k) * fulltextWeight;
48
+ const existing = scoreMap.get(item.id);
49
+ if (existing) {
50
+ existing.rrfScore += rrfScore;
51
+ existing.fulltextRank = rank;
52
+ // Merge additional data if not present
53
+ existing.data = { ...item, ...existing.data };
54
+ }
55
+ else {
56
+ const { id: _id, rank: _, ...data } = item;
57
+ scoreMap.set(item.id, {
58
+ id: item.id,
59
+ rrfScore,
60
+ fulltextRank: rank,
61
+ data: data,
62
+ });
63
+ }
64
+ });
65
+ // Convert to array and sort by RRF score (descending)
66
+ const merged = Array.from(scoreMap.values());
67
+ merged.sort((a, b) => b.rrfScore - a.rrfScore);
68
+ if (process.env.NODE_ENV === "development") {
69
+ // eslint-disable-next-line no-console
70
+ console.log("[Search] RRF merge completed:", {
71
+ vectorCount: vectorResults.length,
72
+ fulltextCount: fulltextResults.length,
73
+ mergedCount: merged.length,
74
+ topScore: merged[0]?.rrfScore,
75
+ });
76
+ }
77
+ return merged;
78
+ }
79
+ /**
80
+ * Convert an array of rows (with an `id` field) into RankedItem[] with 1-based ranks.
81
+ *
82
+ * The array order is preserved and used for rank assignment.
83
+ * All fields from each row are spread into the resulting RankedItem.
84
+ *
85
+ * @param rows - Array of objects that each contain at least an `id: string` field
86
+ * @returns RankedItem[] with rank starting from 1
87
+ */
88
+ export function toRankedItems(rows) {
89
+ return rows.map((row, index) => ({
90
+ ...row,
91
+ rank: index + 1,
92
+ }));
93
+ }
94
+ /**
95
+ * Calculate effective score from RRF for display purposes
96
+ * Normalizes the RRF score to a 0-1 range
97
+ *
98
+ * @param rrfScore - Raw RRF score
99
+ * @param maxPossibleScore - Maximum possible score (sum of max vector and fulltext scores)
100
+ * @returns Normalized similarity score (0-1)
101
+ */
102
+ export function normalizeRRFScore(rrfScore, maxPossibleScore) {
103
+ // Default max score: best possible rank (1) in both searches with default weights
104
+ const defaultMax = calculateRRF(1, 60) * 0.6 + calculateRRF(1, 60) * 0.4;
105
+ const maxScore = maxPossibleScore ?? defaultMax;
106
+ return Math.min(1, rrfScore / maxScore);
107
+ }
108
+ //# sourceMappingURL=rrf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rrf.js","sourceRoot":"","sources":["../../src/search/rrf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Search service type definitions
3
+ *
4
+ * WebDesign専用 - Layout (SectionPattern) and Motion (MotionPattern) search
5
+ */
6
+ /**
7
+ * Search filter options for WebDesign patterns
8
+ */
9
+ export interface SearchFilters {
10
+ /** Pattern type filter (hero, feature, cta, footer, etc.) */
11
+ type?: string | undefined;
12
+ /** Trigger filter for motion patterns (scroll, hover, click, load) */
13
+ trigger?: string | undefined;
14
+ /** Category filter for motion patterns (entrance, exit, emphasis, etc.) */
15
+ category?: string | undefined;
16
+ /** Tag filters */
17
+ tags?: string[] | undefined;
18
+ /** Page ID filter */
19
+ pageId?: string | undefined;
20
+ }
21
+ /**
22
+ * Search options for all search methods
23
+ */
24
+ export interface SearchOptions {
25
+ /** Maximum number of results to return */
26
+ limit: number;
27
+ /** Offset for pagination */
28
+ offset?: number | undefined;
29
+ /** Search filters */
30
+ filters?: SearchFilters | undefined;
31
+ /** Summary mode: returns only id, name, similarity (default: false) */
32
+ summary?: boolean | undefined;
33
+ }
34
+ /**
35
+ * Hybrid search options extending base options
36
+ */
37
+ export interface HybridSearchOptions extends SearchOptions {
38
+ /** Weight for vector search results (default 0.6) */
39
+ vectorWeight?: number | undefined;
40
+ /** Weight for full-text search results (default 0.4) */
41
+ fulltextWeight?: number | undefined;
42
+ /** Minimum similarity threshold (0-1) */
43
+ minSimilarity?: number | undefined;
44
+ }
45
+ /**
46
+ * Individual search result item for WebDesign patterns
47
+ */
48
+ export interface SearchResultItem {
49
+ id: string;
50
+ name: string;
51
+ type: string;
52
+ description: string | undefined;
53
+ similarity: number;
54
+ /** HTML snippet for layout patterns */
55
+ htmlSnippet?: string | undefined;
56
+ /** Raw CSS for motion patterns */
57
+ rawCss?: string | undefined;
58
+ /** Trigger type for motion patterns */
59
+ trigger?: string | undefined;
60
+ /** Category for motion patterns */
61
+ category?: string | undefined;
62
+ /** Associated page ID */
63
+ pageId?: string | undefined;
64
+ createdAt: Date;
65
+ }
66
+ /**
67
+ * Summary search result item (lightweight, only essential fields)
68
+ */
69
+ export interface SummarySearchResultItem {
70
+ id: string;
71
+ name: string;
72
+ similarity: number;
73
+ }
74
+ /**
75
+ * Search result with pagination info
76
+ */
77
+ export interface SearchResult {
78
+ items: SearchResultItem[];
79
+ total: number;
80
+ limit: number;
81
+ offset: number;
82
+ searchTimeMs?: number;
83
+ /** Summary mode flag (only present when summary=true) */
84
+ _summary_mode?: true;
85
+ }
86
+ /**
87
+ * Summary search result with pagination info (lightweight response)
88
+ */
89
+ export interface SummarySearchResult {
90
+ items: SummarySearchResultItem[];
91
+ total: number;
92
+ limit: number;
93
+ offset: number;
94
+ searchTimeMs?: number;
95
+ /** Summary mode flag (always true for summary results) */
96
+ _summary_mode: true;
97
+ }
98
+ /**
99
+ * Vector search raw result from database (section_patterns / motion_patterns)
100
+ */
101
+ export interface VectorSearchRawResult {
102
+ id: string;
103
+ name: string;
104
+ type: string;
105
+ description?: string;
106
+ similarity: number;
107
+ html_snippet?: string;
108
+ raw_css?: string;
109
+ trigger?: string;
110
+ category?: string;
111
+ page_id?: string;
112
+ created_at: Date;
113
+ }
114
+ /**
115
+ * Full-text search raw result from database
116
+ */
117
+ export interface FullTextSearchRawResult {
118
+ id: string;
119
+ name: string;
120
+ type: string;
121
+ description?: string;
122
+ rank: number;
123
+ html_snippet?: string;
124
+ raw_css?: string;
125
+ trigger?: string;
126
+ category?: string;
127
+ page_id?: string;
128
+ created_at: Date;
129
+ }
130
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/search/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ // SPDX-FileCopyrightText: 2026 TKMD and Reftrix Contributors
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ export {};
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/search/types.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,yCAAyC"}
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@reftrixmcp/ml",
3
+ "version": "0.1.7",
4
+ "license": "AGPL-3.0-only",
5
+ "type": "module",
6
+ "description": "ML/Embedding services for Reftrix",
7
+ "files": [
8
+ "dist/",
9
+ "src/"
10
+ ],
11
+ "main": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.js"
17
+ },
18
+ "./embeddings": {
19
+ "types": "./dist/embeddings/index.d.ts",
20
+ "default": "./dist/embeddings/index.js"
21
+ },
22
+ "./search": {
23
+ "types": "./dist/search/index.d.ts",
24
+ "default": "./dist/search/index.js"
25
+ },
26
+ "./dinov2": {
27
+ "types": "./dist/dinov2/index.d.ts",
28
+ "default": "./dist/dinov2/index.js"
29
+ }
30
+ },
31
+ "dependencies": {
32
+ "@huggingface/transformers": "^3.8.1",
33
+ "onnxruntime-node": "1.21.0",
34
+ "p-limit": "^3.1.0",
35
+ "zod": "^3.24.0"
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "^22.0.0",
39
+ "@vitest/coverage-v8": "^4.0.14",
40
+ "typescript": "^5.9.0",
41
+ "vitest": "^4.0.14",
42
+ "@reftrixmcp/config": "0.1.7"
43
+ },
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "https://github.com/TKMD/ReftrixMCP.git",
47
+ "directory": "packages/ml"
48
+ },
49
+ "homepage": "https://github.com/TKMD/ReftrixMCP#readme",
50
+ "bugs": {
51
+ "url": "https://github.com/TKMD/ReftrixMCP/issues"
52
+ },
53
+ "scripts": {
54
+ "build": "tsc",
55
+ "dev": "tsc --watch",
56
+ "lint": "eslint src --ext .ts",
57
+ "lint:fix": "eslint src --ext .ts --fix",
58
+ "typecheck": "tsc --noEmit",
59
+ "test": "vitest run",
60
+ "test:watch": "vitest",
61
+ "test:coverage": "vitest run --coverage",
62
+ "download:dinov2": "tsx scripts/download-dinov2.ts",
63
+ "clean": "rm -rf dist node_modules .turbo"
64
+ }
65
+ }
@@ -0,0 +1,21 @@
1
+ // SPDX-FileCopyrightText: 2026 TKMD and Reftrix Contributors
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+
4
+ /**
5
+ * DINOv2 visual embedding service exports
6
+ */
7
+
8
+ export { DINOv2Service, DINOV2_EMBEDDING_DIMENSION, DINOV2_INPUT_SIZE } from "./service.js";
9
+ export type { DINOv2ServiceConfig } from "./service.js";
10
+
11
+ export type {
12
+ DINOv2WorkerInitMessage,
13
+ DINOv2WorkerInferMessage,
14
+ DINOv2WorkerDisposeMessage,
15
+ DINOv2WorkerMessage,
16
+ DINOv2WorkerInitResponse,
17
+ DINOv2WorkerInferResponse,
18
+ DINOv2WorkerDisposeResponse,
19
+ DINOv2WorkerErrorResponse,
20
+ DINOv2WorkerResponse,
21
+ } from "./worker-thread-types.js";