@contiva/sapbtp-docs-mcp 1.0.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.
Files changed (91) hide show
  1. package/LICENSE +395 -0
  2. package/README.md +386 -0
  3. package/build/cache/embedding-cache.d.ts +39 -0
  4. package/build/cache/embedding-cache.d.ts.map +1 -0
  5. package/build/cache/embedding-cache.js +105 -0
  6. package/build/cache/embedding-cache.js.map +1 -0
  7. package/build/cache/file-cache.d.ts +40 -0
  8. package/build/cache/file-cache.d.ts.map +1 -0
  9. package/build/cache/file-cache.js +124 -0
  10. package/build/cache/file-cache.js.map +1 -0
  11. package/build/cache/search-cache.d.ts +39 -0
  12. package/build/cache/search-cache.d.ts.map +1 -0
  13. package/build/cache/search-cache.js +97 -0
  14. package/build/cache/search-cache.js.map +1 -0
  15. package/build/index.d.ts +3 -0
  16. package/build/index.d.ts.map +1 -0
  17. package/build/index.js +17 -0
  18. package/build/index.js.map +1 -0
  19. package/build/indexing/file-registry.d.ts +47 -0
  20. package/build/indexing/file-registry.d.ts.map +1 -0
  21. package/build/indexing/file-registry.js +130 -0
  22. package/build/indexing/file-registry.js.map +1 -0
  23. package/build/indexing/topic-index.d.ts +57 -0
  24. package/build/indexing/topic-index.d.ts.map +1 -0
  25. package/build/indexing/topic-index.js +181 -0
  26. package/build/indexing/topic-index.js.map +1 -0
  27. package/build/parsers/links.d.ts +14 -0
  28. package/build/parsers/links.d.ts.map +1 -0
  29. package/build/parsers/links.js +80 -0
  30. package/build/parsers/links.js.map +1 -0
  31. package/build/parsers/markdown.d.ts +10 -0
  32. package/build/parsers/markdown.d.ts.map +1 -0
  33. package/build/parsers/markdown.js +120 -0
  34. package/build/parsers/markdown.js.map +1 -0
  35. package/build/parsers/metadata.d.ts +19 -0
  36. package/build/parsers/metadata.d.ts.map +1 -0
  37. package/build/parsers/metadata.js +63 -0
  38. package/build/parsers/metadata.js.map +1 -0
  39. package/build/search/fulltext.d.ts +20 -0
  40. package/build/search/fulltext.d.ts.map +1 -0
  41. package/build/search/fulltext.js +117 -0
  42. package/build/search/fulltext.js.map +1 -0
  43. package/build/search/ranking.d.ts +27 -0
  44. package/build/search/ranking.d.ts.map +1 -0
  45. package/build/search/ranking.js +119 -0
  46. package/build/search/ranking.js.map +1 -0
  47. package/build/search/semantic.d.ts +53 -0
  48. package/build/search/semantic.d.ts.map +1 -0
  49. package/build/search/semantic.js +260 -0
  50. package/build/search/semantic.js.map +1 -0
  51. package/build/search/title.d.ts +18 -0
  52. package/build/search/title.d.ts.map +1 -0
  53. package/build/search/title.js +95 -0
  54. package/build/search/title.js.map +1 -0
  55. package/build/server.d.ts +32 -0
  56. package/build/server.d.ts.map +1 -0
  57. package/build/server.js +183 -0
  58. package/build/server.js.map +1 -0
  59. package/build/tools/get-related.d.ts +64 -0
  60. package/build/tools/get-related.d.ts.map +1 -0
  61. package/build/tools/get-related.js +203 -0
  62. package/build/tools/get-related.js.map +1 -0
  63. package/build/tools/list-topics.d.ts +43 -0
  64. package/build/tools/list-topics.d.ts.map +1 -0
  65. package/build/tools/list-topics.js +63 -0
  66. package/build/tools/list-topics.js.map +1 -0
  67. package/build/tools/read-article.d.ts +42 -0
  68. package/build/tools/read-article.d.ts.map +1 -0
  69. package/build/tools/read-article.js +89 -0
  70. package/build/tools/read-article.js.map +1 -0
  71. package/build/tools/search.d.ts +57 -0
  72. package/build/tools/search.d.ts.map +1 -0
  73. package/build/tools/search.js +109 -0
  74. package/build/tools/search.js.map +1 -0
  75. package/build/types/index.d.ts +179 -0
  76. package/build/types/index.d.ts.map +1 -0
  77. package/build/types/index.js +2 -0
  78. package/build/types/index.js.map +1 -0
  79. package/build/utils/docs-downloader.d.ts +9 -0
  80. package/build/utils/docs-downloader.d.ts.map +1 -0
  81. package/build/utils/docs-downloader.js +82 -0
  82. package/build/utils/docs-downloader.js.map +1 -0
  83. package/build/utils/paths.d.ts +67 -0
  84. package/build/utils/paths.d.ts.map +1 -0
  85. package/build/utils/paths.js +132 -0
  86. package/build/utils/paths.js.map +1 -0
  87. package/build/utils/text-processing.d.ts +62 -0
  88. package/build/utils/text-processing.d.ts.map +1 -0
  89. package/build/utils/text-processing.js +214 -0
  90. package/build/utils/text-processing.js.map +1 -0
  91. package/package.json +63 -0
@@ -0,0 +1,117 @@
1
+ import { normalizeText, tokenize, extractSnippet, containsAllWords } from '../utils/text-processing.js';
2
+ /**
3
+ * Full-text search implementation
4
+ */
5
+ export class FullTextSearch {
6
+ registry;
7
+ fileCache;
8
+ constructor(registry, fileCache) {
9
+ this.registry = registry;
10
+ this.fileCache = fileCache;
11
+ }
12
+ /**
13
+ * Performs full-text search across documentation
14
+ */
15
+ async search(options) {
16
+ const { query, area = 'all', limit = 20 } = options;
17
+ // Get files to search
18
+ const files = area === 'all'
19
+ ? this.registry.getAllFiles()
20
+ : this.registry.getByArea(area);
21
+ // Score each file
22
+ const scoredResults = [];
23
+ // Limit concurrent file reads to 50
24
+ const batchSize = 50;
25
+ for (let i = 0; i < Math.min(files.length, 200); i += batchSize) {
26
+ const batch = files.slice(i, i + batchSize);
27
+ const batchResults = await Promise.all(batch.map(async (file) => {
28
+ try {
29
+ const doc = await this.fileCache.get(file.filePath);
30
+ const score = this.scoreDocument(doc.cleanText, doc.title, query);
31
+ if (score > 0) {
32
+ const snippet = extractSnippet(doc.cleanText, query, 100);
33
+ return {
34
+ result: {
35
+ filePath: file.filePath,
36
+ relativePath: file.relativePath,
37
+ title: doc.title,
38
+ loioId: doc.loioId,
39
+ snippet,
40
+ score,
41
+ matchType: 'fulltext',
42
+ area: file.area,
43
+ },
44
+ score,
45
+ };
46
+ }
47
+ return null;
48
+ }
49
+ catch (error) {
50
+ // Skip files that can't be read
51
+ return null;
52
+ }
53
+ }));
54
+ scoredResults.push(...batchResults.filter((r) => r !== null));
55
+ }
56
+ // Sort by score (descending)
57
+ scoredResults.sort((a, b) => b.score - a.score);
58
+ // Return top results
59
+ return scoredResults.slice(0, limit).map(r => r.result);
60
+ }
61
+ /**
62
+ * Scores a document based on query relevance
63
+ */
64
+ scoreDocument(content, title, query) {
65
+ const normalizedContent = normalizeText(content);
66
+ const normalizedTitle = normalizeText(title);
67
+ const normalizedQuery = normalizeText(query);
68
+ const queryTokens = tokenize(query);
69
+ let score = 0;
70
+ // Exact match in title (highest score)
71
+ if (normalizedTitle.includes(normalizedQuery)) {
72
+ score += 100;
73
+ }
74
+ // Exact match in content
75
+ if (normalizedContent.includes(normalizedQuery)) {
76
+ score += 50;
77
+ }
78
+ // Word boundary matches in title
79
+ for (const token of queryTokens) {
80
+ const regex = new RegExp(`\\b${escapeRegex(token)}\\b`, 'i');
81
+ if (regex.test(title)) {
82
+ score += 30;
83
+ }
84
+ }
85
+ // Word boundary matches in content
86
+ for (const token of queryTokens) {
87
+ const regex = new RegExp(`\\b${escapeRegex(token)}\\b`, 'i');
88
+ if (regex.test(content)) {
89
+ score += 10;
90
+ }
91
+ }
92
+ // Partial matches in content
93
+ for (const token of queryTokens) {
94
+ if (normalizedContent.includes(token)) {
95
+ score += 5;
96
+ }
97
+ }
98
+ // Bonus for containing all query words
99
+ if (containsAllWords(content, query)) {
100
+ score += 20;
101
+ }
102
+ // Position bonus (earlier mentions score higher)
103
+ const firstIndex = normalizedContent.indexOf(normalizedQuery);
104
+ if (firstIndex !== -1) {
105
+ const positionBonus = Math.max(0, 20 - Math.floor(firstIndex / 100));
106
+ score += positionBonus;
107
+ }
108
+ return score;
109
+ }
110
+ }
111
+ /**
112
+ * Escapes special regex characters
113
+ */
114
+ function escapeRegex(str) {
115
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
116
+ }
117
+ //# sourceMappingURL=fulltext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fulltext.js","sourceRoot":"","sources":["../../src/search/fulltext.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { SearchResult } from '../types/index.js';
2
+ /**
3
+ * Combines and ranks search results from multiple search methods
4
+ */
5
+ export declare class SearchRanking {
6
+ /**
7
+ * Combines results from multiple search methods with weighted scoring
8
+ */
9
+ combineResults(fulltextResults: SearchResult[], titleResults: SearchResult[], semanticResults: SearchResult[]): SearchResult[];
10
+ /**
11
+ * Calculates weighted total score
12
+ */
13
+ private calculateTotalScore;
14
+ /**
15
+ * Normalizes scores to 0-100 range
16
+ */
17
+ normalizeScores(results: SearchResult[]): SearchResult[];
18
+ /**
19
+ * Deduplicates results (keeps highest scoring)
20
+ */
21
+ deduplicateResults(results: SearchResult[]): SearchResult[];
22
+ /**
23
+ * Filters results by minimum score threshold
24
+ */
25
+ filterByScore(results: SearchResult[], minScore: number): SearchResult[];
26
+ }
27
+ //# sourceMappingURL=ranking.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ranking.d.ts","sourceRoot":"","sources":["../../src/search/ranking.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;GAEG;AACH,qBAAa,aAAa;IACxB;;OAEG;IACH,cAAc,CACZ,eAAe,EAAE,YAAY,EAAE,EAC/B,YAAY,EAAE,YAAY,EAAE,EAC5B,eAAe,EAAE,YAAY,EAAE,GAC9B,YAAY,EAAE;IA+EjB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAW3B;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE;IAiBxD;;OAEG;IACH,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE;IAc3D;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE;CAGzE"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Combines and ranks search results from multiple search methods
3
+ */
4
+ export class SearchRanking {
5
+ /**
6
+ * Combines results from multiple search methods with weighted scoring
7
+ */
8
+ combineResults(fulltextResults, titleResults, semanticResults) {
9
+ // Weights for each search type
10
+ const weights = {
11
+ fulltext: 0.4,
12
+ title: 0.3,
13
+ semantic: 0.3,
14
+ };
15
+ // Create a map to track best score per file
16
+ const fileScores = new Map();
17
+ // Process fulltext results
18
+ for (const result of fulltextResults) {
19
+ const existing = fileScores.get(result.filePath);
20
+ if (!existing) {
21
+ fileScores.set(result.filePath, {
22
+ result: { ...result, matchType: 'combined' },
23
+ scores: { fulltext: result.score, title: 0, semantic: 0 },
24
+ totalScore: result.score * weights.fulltext,
25
+ });
26
+ }
27
+ else {
28
+ existing.scores.fulltext = Math.max(existing.scores.fulltext, result.score);
29
+ existing.totalScore = this.calculateTotalScore(existing.scores, weights);
30
+ }
31
+ }
32
+ // Process title results
33
+ for (const result of titleResults) {
34
+ const existing = fileScores.get(result.filePath);
35
+ if (!existing) {
36
+ fileScores.set(result.filePath, {
37
+ result: { ...result, matchType: 'combined' },
38
+ scores: { fulltext: 0, title: result.score, semantic: 0 },
39
+ totalScore: result.score * weights.title,
40
+ });
41
+ }
42
+ else {
43
+ existing.scores.title = Math.max(existing.scores.title, result.score);
44
+ existing.totalScore = this.calculateTotalScore(existing.scores, weights);
45
+ // Prefer snippet from title search if score is high
46
+ if (result.score > existing.scores.fulltext) {
47
+ existing.result.snippet = result.snippet;
48
+ }
49
+ }
50
+ }
51
+ // Process semantic results
52
+ for (const result of semanticResults) {
53
+ const existing = fileScores.get(result.filePath);
54
+ if (!existing) {
55
+ fileScores.set(result.filePath, {
56
+ result: { ...result, matchType: 'combined' },
57
+ scores: { fulltext: 0, title: 0, semantic: result.score },
58
+ totalScore: result.score * weights.semantic,
59
+ });
60
+ }
61
+ else {
62
+ existing.scores.semantic = Math.max(existing.scores.semantic, result.score);
63
+ existing.totalScore = this.calculateTotalScore(existing.scores, weights);
64
+ }
65
+ }
66
+ // Convert to array and sort by total score
67
+ const combinedResults = Array.from(fileScores.values())
68
+ .map(({ result, totalScore }) => ({
69
+ ...result,
70
+ score: totalScore,
71
+ }))
72
+ .sort((a, b) => b.score - a.score);
73
+ return combinedResults;
74
+ }
75
+ /**
76
+ * Calculates weighted total score
77
+ */
78
+ calculateTotalScore(scores, weights) {
79
+ return (scores.fulltext * weights.fulltext +
80
+ scores.title * weights.title +
81
+ scores.semantic * weights.semantic);
82
+ }
83
+ /**
84
+ * Normalizes scores to 0-100 range
85
+ */
86
+ normalizeScores(results) {
87
+ if (results.length === 0) {
88
+ return results;
89
+ }
90
+ const maxScore = Math.max(...results.map(r => r.score));
91
+ if (maxScore === 0) {
92
+ return results;
93
+ }
94
+ return results.map(result => ({
95
+ ...result,
96
+ score: (result.score / maxScore) * 100,
97
+ }));
98
+ }
99
+ /**
100
+ * Deduplicates results (keeps highest scoring)
101
+ */
102
+ deduplicateResults(results) {
103
+ const fileMap = new Map();
104
+ for (const result of results) {
105
+ const existing = fileMap.get(result.filePath);
106
+ if (!existing || result.score > existing.score) {
107
+ fileMap.set(result.filePath, result);
108
+ }
109
+ }
110
+ return Array.from(fileMap.values());
111
+ }
112
+ /**
113
+ * Filters results by minimum score threshold
114
+ */
115
+ filterByScore(results, minScore) {
116
+ return results.filter(result => result.score >= minScore);
117
+ }
118
+ }
119
+ //# sourceMappingURL=ranking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ranking.js","sourceRoot":"","sources":["../../src/search/ranking.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type { SemanticSearchOptions, SearchResult } from '../types/index.js';
2
+ import { FileRegistry } from '../indexing/file-registry.js';
3
+ import { FileCache } from '../cache/file-cache.js';
4
+ /**
5
+ * Semantic search using embeddings
6
+ */
7
+ export declare class SemanticSearch {
8
+ private registry;
9
+ private fileCache;
10
+ private embeddingCache;
11
+ private embeddingData;
12
+ private embeddingModel;
13
+ private provider;
14
+ private modelName;
15
+ constructor(registry: FileRegistry, fileCache: FileCache);
16
+ /**
17
+ * Gets the model name for the configured provider
18
+ */
19
+ private getModelName;
20
+ /**
21
+ * Initializes the semantic search (loads or builds embeddings)
22
+ */
23
+ initialize(): Promise<void>;
24
+ /**
25
+ * Builds embeddings for all documents
26
+ */
27
+ private buildEmbeddings;
28
+ /**
29
+ * Generates an embedding for text
30
+ */
31
+ private embedText;
32
+ /**
33
+ * Generates embedding using local model (@xenova/transformers)
34
+ */
35
+ private embedTextLocal;
36
+ /**
37
+ * Generates embedding using Voyage AI (stub - requires voyageai package)
38
+ */
39
+ private embedTextVoyage;
40
+ /**
41
+ * Generates embedding using OpenAI (stub - requires openai package)
42
+ */
43
+ private embedTextOpenAI;
44
+ /**
45
+ * Performs semantic search
46
+ */
47
+ search(options: SemanticSearchOptions): Promise<SearchResult[]>;
48
+ /**
49
+ * Gets embedding for a specific document (for related articles)
50
+ */
51
+ getDocumentEmbedding(filePath: string): Promise<number[] | null>;
52
+ }
53
+ //# sourceMappingURL=semantic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../../src/search/semantic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,YAAY,EAAyD,MAAM,mBAAmB,CAAC;AACpI,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAQnD;;GAEG;AACH,qBAAa,cAAc;IAQvB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,SAAS;IARnB,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,aAAa,CAAmC;IACxD,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,SAAS,CAAS;gBAGhB,QAAQ,EAAE,YAAY,EACtB,SAAS,EAAE,SAAS;IAO9B;;OAEG;IACH,OAAO,CAAC,YAAY;IAapB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBjC;;OAEG;YACW,eAAe;IAwD7B;;OAEG;YACW,SAAS;IAYvB;;OAEG;YACW,cAAc;IAwB5B;;OAEG;YACW,eAAe;IAgB7B;;OAEG;YACW,eAAe;IAgB7B;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAqErE;;OAEG;IACG,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;CA+BvE"}
@@ -0,0 +1,260 @@
1
+ import { EmbeddingCache } from '../cache/embedding-cache.js';
2
+ import { chunkText, cosineSimilarity, truncateText } from '../utils/text-processing.js';
3
+ // Dynamic imports for optional dependencies
4
+ let pipeline = null;
5
+ let env = null;
6
+ /**
7
+ * Semantic search using embeddings
8
+ */
9
+ export class SemanticSearch {
10
+ registry;
11
+ fileCache;
12
+ embeddingCache;
13
+ embeddingData = null;
14
+ embeddingModel = null;
15
+ provider;
16
+ modelName;
17
+ constructor(registry, fileCache) {
18
+ this.registry = registry;
19
+ this.fileCache = fileCache;
20
+ this.embeddingCache = new EmbeddingCache();
21
+ this.provider = process.env.EMBEDDING_PROVIDER || 'local';
22
+ this.modelName = this.getModelName();
23
+ }
24
+ /**
25
+ * Gets the model name for the configured provider
26
+ */
27
+ getModelName() {
28
+ switch (this.provider) {
29
+ case 'local':
30
+ return 'Xenova/all-MiniLM-L6-v2';
31
+ case 'voyage':
32
+ return 'voyage-3';
33
+ case 'openai':
34
+ return 'text-embedding-3-small';
35
+ default:
36
+ return 'Xenova/all-MiniLM-L6-v2';
37
+ }
38
+ }
39
+ /**
40
+ * Initializes the semantic search (loads or builds embeddings)
41
+ */
42
+ async initialize() {
43
+ console.error('Initializing semantic search...');
44
+ // Try to load from cache
45
+ const cached = await this.embeddingCache.load();
46
+ if (cached && cached.provider === this.provider && cached.model === this.modelName) {
47
+ console.error(`Loaded ${cached.embeddings.length} embeddings from cache`);
48
+ this.embeddingData = cached;
49
+ return;
50
+ }
51
+ // Build new embeddings
52
+ console.error('Building embeddings index (this may take 10-15 minutes for local embeddings)...');
53
+ await this.buildEmbeddings();
54
+ }
55
+ /**
56
+ * Builds embeddings for all documents
57
+ */
58
+ async buildEmbeddings() {
59
+ const startTime = Date.now();
60
+ const files = this.registry.getAllFiles();
61
+ const embeddings = [];
62
+ console.error(`Processing ${files.length} files...`);
63
+ // Process in batches to show progress
64
+ const batchSize = 100;
65
+ for (let i = 0; i < files.length; i += batchSize) {
66
+ const batch = files.slice(i, i + batchSize);
67
+ console.error(`Processing batch ${Math.floor(i / batchSize) + 1}/${Math.ceil(files.length / batchSize)}...`);
68
+ for (const file of batch) {
69
+ try {
70
+ const doc = await this.fileCache.get(file.filePath);
71
+ // Chunk the text
72
+ const chunks = chunkText(doc.cleanText, 500, 50);
73
+ // Generate embeddings for each chunk
74
+ for (const chunk of chunks) {
75
+ const embedding = await this.embedText(chunk.text);
76
+ embeddings.push({
77
+ filePath: file.filePath,
78
+ title: doc.title,
79
+ loioId: doc.loioId,
80
+ chunkIndex: chunk.chunkIndex,
81
+ text: truncateText(chunk.text, 500),
82
+ embedding,
83
+ });
84
+ }
85
+ }
86
+ catch (error) {
87
+ console.error(`Error processing ${file.filePath}:`, error);
88
+ }
89
+ }
90
+ }
91
+ const elapsed = (Date.now() - startTime) / 1000;
92
+ console.error(`Built ${embeddings.length} embeddings in ${elapsed.toFixed(1)}s`);
93
+ // Save to cache
94
+ this.embeddingData = {
95
+ version: '1.0.0',
96
+ model: this.modelName,
97
+ provider: this.provider,
98
+ createdAt: new Date().toISOString(),
99
+ embeddings,
100
+ };
101
+ await this.embeddingCache.save(this.embeddingData);
102
+ }
103
+ /**
104
+ * Generates an embedding for text
105
+ */
106
+ async embedText(text) {
107
+ if (this.provider === 'local') {
108
+ return await this.embedTextLocal(text);
109
+ }
110
+ else if (this.provider === 'voyage') {
111
+ return await this.embedTextVoyage(text);
112
+ }
113
+ else if (this.provider === 'openai') {
114
+ return await this.embedTextOpenAI(text);
115
+ }
116
+ throw new Error(`Unsupported embedding provider: ${this.provider}`);
117
+ }
118
+ /**
119
+ * Generates embedding using local model (@xenova/transformers)
120
+ */
121
+ async embedTextLocal(text) {
122
+ // Lazy load transformers
123
+ if (!pipeline) {
124
+ const transformers = await import('@xenova/transformers');
125
+ pipeline = transformers.pipeline;
126
+ env = transformers.env;
127
+ // Disable local model cache (use default cache)
128
+ env.allowLocalModels = false;
129
+ }
130
+ // Initialize model if needed
131
+ if (!this.embeddingModel) {
132
+ console.error('Loading local embedding model (first time only)...');
133
+ this.embeddingModel = await pipeline('feature-extraction', this.modelName);
134
+ }
135
+ // Generate embedding
136
+ const output = await this.embeddingModel(text, { pooling: 'mean', normalize: true });
137
+ // Convert to array
138
+ return Array.from(output.data);
139
+ }
140
+ /**
141
+ * Generates embedding using Voyage AI (stub - requires voyageai package)
142
+ */
143
+ async embedTextVoyage(text) {
144
+ try {
145
+ const { VoyageAIClient } = await import('voyageai');
146
+ const client = new VoyageAIClient({ apiKey: process.env.VOYAGE_API_KEY });
147
+ const result = await client.embed({
148
+ input: text,
149
+ model: this.modelName,
150
+ });
151
+ return result.data?.[0]?.embedding || [];
152
+ }
153
+ catch (error) {
154
+ throw new Error('Voyage AI not available. Install with: npm install voyageai');
155
+ }
156
+ }
157
+ /**
158
+ * Generates embedding using OpenAI (stub - requires openai package)
159
+ */
160
+ async embedTextOpenAI(text) {
161
+ try {
162
+ const { OpenAI } = await import('openai');
163
+ const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
164
+ const result = await client.embeddings.create({
165
+ input: text,
166
+ model: this.modelName,
167
+ });
168
+ return result.data[0].embedding;
169
+ }
170
+ catch (error) {
171
+ throw new Error('OpenAI not available. Install with: npm install openai');
172
+ }
173
+ }
174
+ /**
175
+ * Performs semantic search
176
+ */
177
+ async search(options) {
178
+ const { query, area = 'all', limit = 20 } = options;
179
+ // Ensure embeddings are loaded
180
+ if (!this.embeddingData) {
181
+ await this.initialize();
182
+ }
183
+ if (!this.embeddingData) {
184
+ throw new Error('Failed to initialize semantic search');
185
+ }
186
+ // Generate embedding for query
187
+ const queryEmbedding = await this.embedText(query);
188
+ // Calculate similarity scores
189
+ const scoredResults = this.embeddingData.embeddings.map(entry => {
190
+ const similarity = cosineSimilarity(queryEmbedding, entry.embedding);
191
+ const score = similarity * 100; // Convert to 0-100 scale
192
+ return {
193
+ entry,
194
+ score,
195
+ };
196
+ });
197
+ // Sort by score
198
+ scoredResults.sort((a, b) => b.score - a.score);
199
+ // Filter by area if specified
200
+ const filtered = area === 'all'
201
+ ? scoredResults
202
+ : scoredResults.filter(r => {
203
+ const file = this.registry.getByPath(r.entry.filePath);
204
+ return file && file.area === area;
205
+ });
206
+ // Group by file (take best chunk per file)
207
+ const fileMap = new Map();
208
+ for (const result of filtered) {
209
+ const existing = fileMap.get(result.entry.filePath);
210
+ if (!existing || result.score > existing.score) {
211
+ fileMap.set(result.entry.filePath, result);
212
+ }
213
+ }
214
+ // Convert to search results
215
+ const results = Array.from(fileMap.values())
216
+ .slice(0, limit)
217
+ .map(({ entry, score }) => {
218
+ const file = this.registry.getByPath(entry.filePath);
219
+ return {
220
+ filePath: entry.filePath,
221
+ relativePath: file?.relativePath || entry.filePath,
222
+ title: entry.title,
223
+ loioId: entry.loioId,
224
+ snippet: entry.text,
225
+ score,
226
+ matchType: 'semantic',
227
+ area: file?.area || 'ISuite',
228
+ };
229
+ });
230
+ return results;
231
+ }
232
+ /**
233
+ * Gets embedding for a specific document (for related articles)
234
+ */
235
+ async getDocumentEmbedding(filePath) {
236
+ if (!this.embeddingData) {
237
+ await this.initialize();
238
+ }
239
+ if (!this.embeddingData) {
240
+ return null;
241
+ }
242
+ // Find embeddings for this file
243
+ const fileEmbeddings = this.embeddingData.embeddings.filter(e => e.filePath === filePath);
244
+ if (fileEmbeddings.length === 0) {
245
+ return null;
246
+ }
247
+ // Average all chunks
248
+ const avgEmbedding = new Array(fileEmbeddings[0].embedding.length).fill(0);
249
+ for (const entry of fileEmbeddings) {
250
+ for (let i = 0; i < entry.embedding.length; i++) {
251
+ avgEmbedding[i] += entry.embedding[i];
252
+ }
253
+ }
254
+ for (let i = 0; i < avgEmbedding.length; i++) {
255
+ avgEmbedding[i] /= fileEmbeddings.length;
256
+ }
257
+ return avgEmbedding;
258
+ }
259
+ }
260
+ //# sourceMappingURL=semantic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic.js","sourceRoot":"","sources":["../../src/search/semantic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { TitleSearchOptions, SearchResult } from '../types/index.js';
2
+ import { FileRegistry } from '../indexing/file-registry.js';
3
+ /**
4
+ * Title-based search implementation
5
+ */
6
+ export declare class TitleSearch {
7
+ private registry;
8
+ constructor(registry: FileRegistry);
9
+ /**
10
+ * Performs title-based search
11
+ */
12
+ search(options: TitleSearchOptions): Promise<SearchResult[]>;
13
+ /**
14
+ * Scores a title based on query relevance
15
+ */
16
+ private scoreTitle;
17
+ }
18
+ //# sourceMappingURL=title.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"title.d.ts","sourceRoot":"","sources":["../../src/search/title.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAG5D;;GAEG;AACH,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAE1C;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAsClE;;OAEG;IACH,OAAO,CAAC,UAAU;CAuDnB"}