@fractalizer/mcp-search 0.1.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 (83) hide show
  1. package/README.md +408 -0
  2. package/dist/constants.d.ts +12 -0
  3. package/dist/constants.d.ts.map +1 -0
  4. package/dist/constants.js +12 -0
  5. package/dist/constants.js.map +1 -0
  6. package/dist/engine/index.d.ts +5 -0
  7. package/dist/engine/index.d.ts.map +1 -0
  8. package/dist/engine/index.js +5 -0
  9. package/dist/engine/index.js.map +1 -0
  10. package/dist/engine/tool-search-engine.d.ts +70 -0
  11. package/dist/engine/tool-search-engine.d.ts.map +1 -0
  12. package/dist/engine/tool-search-engine.js +213 -0
  13. package/dist/engine/tool-search-engine.js.map +1 -0
  14. package/dist/index.d.ts +20 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +23 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/scoring/strategy-weights.d.ts +20 -0
  19. package/dist/scoring/strategy-weights.d.ts.map +1 -0
  20. package/dist/scoring/strategy-weights.js +51 -0
  21. package/dist/scoring/strategy-weights.js.map +1 -0
  22. package/dist/strategies/category-search.strategy.d.ts +30 -0
  23. package/dist/strategies/category-search.strategy.d.ts.map +1 -0
  24. package/dist/strategies/category-search.strategy.js +81 -0
  25. package/dist/strategies/category-search.strategy.js.map +1 -0
  26. package/dist/strategies/description-search.strategy.d.ts +38 -0
  27. package/dist/strategies/description-search.strategy.d.ts.map +1 -0
  28. package/dist/strategies/description-search.strategy.js +68 -0
  29. package/dist/strategies/description-search.strategy.js.map +1 -0
  30. package/dist/strategies/fuzzy-search.strategy.d.ts +65 -0
  31. package/dist/strategies/fuzzy-search.strategy.d.ts.map +1 -0
  32. package/dist/strategies/fuzzy-search.strategy.js +158 -0
  33. package/dist/strategies/fuzzy-search.strategy.js.map +1 -0
  34. package/dist/strategies/index.d.ts +12 -0
  35. package/dist/strategies/index.d.ts.map +1 -0
  36. package/dist/strategies/index.js +11 -0
  37. package/dist/strategies/index.js.map +1 -0
  38. package/dist/strategies/name-search.strategy.d.ts +35 -0
  39. package/dist/strategies/name-search.strategy.d.ts.map +1 -0
  40. package/dist/strategies/name-search.strategy.js +99 -0
  41. package/dist/strategies/name-search.strategy.js.map +1 -0
  42. package/dist/strategies/search-strategy.interface.d.ts +28 -0
  43. package/dist/strategies/search-strategy.interface.d.ts.map +1 -0
  44. package/dist/strategies/search-strategy.interface.js +12 -0
  45. package/dist/strategies/search-strategy.interface.js.map +1 -0
  46. package/dist/strategies/weighted-combined.strategy.d.ts +37 -0
  47. package/dist/strategies/weighted-combined.strategy.d.ts.map +1 -0
  48. package/dist/strategies/weighted-combined.strategy.js +90 -0
  49. package/dist/strategies/weighted-combined.strategy.js.map +1 -0
  50. package/dist/tools/index.d.ts +7 -0
  51. package/dist/tools/index.d.ts.map +1 -0
  52. package/dist/tools/index.js +7 -0
  53. package/dist/tools/index.js.map +1 -0
  54. package/dist/tools/search-tools.definition.d.ts +18 -0
  55. package/dist/tools/search-tools.definition.d.ts.map +1 -0
  56. package/dist/tools/search-tools.definition.js +93 -0
  57. package/dist/tools/search-tools.definition.js.map +1 -0
  58. package/dist/tools/search-tools.metadata.d.ts +12 -0
  59. package/dist/tools/search-tools.metadata.d.ts.map +1 -0
  60. package/dist/tools/search-tools.metadata.js +57 -0
  61. package/dist/tools/search-tools.metadata.js.map +1 -0
  62. package/dist/tools/search-tools.schema.d.ts +31 -0
  63. package/dist/tools/search-tools.schema.d.ts.map +1 -0
  64. package/dist/tools/search-tools.schema.js +60 -0
  65. package/dist/tools/search-tools.schema.js.map +1 -0
  66. package/dist/tools/search-tools.tool.d.ts +57 -0
  67. package/dist/tools/search-tools.tool.d.ts.map +1 -0
  68. package/dist/tools/search-tools.tool.js +141 -0
  69. package/dist/tools/search-tools.tool.js.map +1 -0
  70. package/dist/tsconfig.tsbuildinfo +1 -0
  71. package/dist/types.d.ts +112 -0
  72. package/dist/types.d.ts.map +1 -0
  73. package/dist/types.js +10 -0
  74. package/dist/types.js.map +1 -0
  75. package/dist/utils/build-index-from-registry.d.ts +28 -0
  76. package/dist/utils/build-index-from-registry.d.ts.map +1 -0
  77. package/dist/utils/build-index-from-registry.js +80 -0
  78. package/dist/utils/build-index-from-registry.js.map +1 -0
  79. package/dist/utils/text-utils.d.ts +48 -0
  80. package/dist/utils/text-utils.d.ts.map +1 -0
  81. package/dist/utils/text-utils.js +50 -0
  82. package/dist/utils/text-utils.js.map +1 -0
  83. package/package.json +79 -0
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Главный класс поисковой системы tools
3
+ *
4
+ * Responsibilities:
5
+ * - Выполнение поиска через стратегии
6
+ * - Фильтрация по категориям и типам
7
+ * - Кеширование результатов
8
+ * - Форматирование результатов по уровню детализации
9
+ * - Lazy loading полных метаданных
10
+ */
11
+ import { DEFAULT_TOOL_SEARCH_LIMIT, DEFAULT_TOOL_SEARCH_DETAIL_LEVEL } from '../constants.js';
12
+ import { tokenize, getShortDescription } from '../utils/text-utils.js';
13
+ /**
14
+ * Поисковый движок для tools
15
+ */
16
+ export class ToolSearchEngine {
17
+ staticIndex;
18
+ toolRegistry;
19
+ searchStrategy;
20
+ cache;
21
+ lazyIndex = null;
22
+ /**
23
+ * Максимальный размер кеша (LRU)
24
+ */
25
+ MAX_CACHE_SIZE = 100;
26
+ constructor(staticIndex, toolRegistry, searchStrategy) {
27
+ this.staticIndex = staticIndex;
28
+ this.toolRegistry = toolRegistry;
29
+ this.searchStrategy = searchStrategy;
30
+ this.cache = new Map();
31
+ }
32
+ /**
33
+ * Получить индекс (статический или динамический из ToolRegistry)
34
+ */
35
+ getIndex() {
36
+ // Если есть статический индекс, используем его
37
+ if (this.staticIndex) {
38
+ return Array.from(this.staticIndex);
39
+ }
40
+ // Иначе генерируем динамический индекс из ToolRegistry (lazy)
41
+ if (!this.lazyIndex) {
42
+ this.lazyIndex = this.buildIndexFromRegistry();
43
+ }
44
+ return this.lazyIndex;
45
+ }
46
+ /**
47
+ * Построить индекс из ToolRegistry
48
+ */
49
+ buildIndexFromRegistry() {
50
+ const index = [];
51
+ const tools = this.toolRegistry.getAllTools();
52
+ for (const tool of tools) {
53
+ const metadata = tool.getMetadata();
54
+ const definition = metadata.definition;
55
+ // Skip tools without required fields
56
+ // Runtime safety: mock objects in tests may not have all required fields
57
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
58
+ if (!definition.name?.length || !definition.description?.length || !metadata.category?.length) {
59
+ continue;
60
+ }
61
+ index.push({
62
+ name: definition.name,
63
+ category: metadata.category,
64
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Runtime safety: mock objects may not have tags
65
+ tags: metadata.tags ? Array.from(metadata.tags) : [],
66
+ isHelper: metadata.isHelper === true,
67
+ nameTokens: tokenize(definition.name),
68
+ descriptionTokens: tokenize(definition.description),
69
+ descriptionShort: getShortDescription(definition.description),
70
+ });
71
+ }
72
+ return index;
73
+ }
74
+ /**
75
+ * Выполнить поиск с кешированием
76
+ */
77
+ search(params) {
78
+ // Генерируем ключ кеша
79
+ const cacheKey = this.getCacheKey(params);
80
+ // Проверяем кеш
81
+ const cached = this.cache.get(cacheKey);
82
+ if (cached) {
83
+ return cached;
84
+ }
85
+ // Выполняем поиск
86
+ const results = this.performSearch(params);
87
+ // Кешируем результат
88
+ this.cache.set(cacheKey, results);
89
+ // Ограничиваем размер кеша (простая LRU стратегия)
90
+ if (this.cache.size > this.MAX_CACHE_SIZE) {
91
+ const firstKey = this.cache.keys().next().value;
92
+ if (firstKey) {
93
+ this.cache.delete(firstKey);
94
+ }
95
+ }
96
+ return results;
97
+ }
98
+ /**
99
+ * Выполнить поиск без кеширования
100
+ */
101
+ performSearch(params) {
102
+ // Фильтруем индекс (статический или динамический)
103
+ const filtered = this.filterIndex(params);
104
+ // Если query пустой или "*", возвращаем все отфильтрованные инструменты
105
+ let searchResults;
106
+ if (!params.query || params.query.trim() === '' || params.query === '*') {
107
+ // Возвращаем все отфильтрованные инструменты (конвертируем в SearchResult)
108
+ searchResults = filtered.map((tool) => ({
109
+ toolName: tool.name,
110
+ score: 1.0, // максимальный score для полного совпадения
111
+ }));
112
+ }
113
+ else {
114
+ // Выполняем поиск по стратегиям
115
+ searchResults = this.searchStrategy.search(params.query, filtered);
116
+ }
117
+ // Применяем лимит
118
+ const totalFound = searchResults.length;
119
+ const limited = searchResults.slice(0, params.limit || DEFAULT_TOOL_SEARCH_LIMIT);
120
+ // Форматируем результаты
121
+ const tools = this.formatResults(limited, params.detailLevel || DEFAULT_TOOL_SEARCH_DETAIL_LEVEL);
122
+ return {
123
+ tools,
124
+ totalFound,
125
+ };
126
+ }
127
+ /**
128
+ * Фильтровать индекс по параметрам
129
+ */
130
+ filterIndex(params) {
131
+ let filtered = this.getIndex();
132
+ // Фильтр по категории
133
+ if (params.category) {
134
+ filtered = filtered.filter((t) => t.category === params.category);
135
+ }
136
+ // Фильтр по типу (helper/api)
137
+ if (params.isHelper !== undefined) {
138
+ filtered = filtered.filter((t) => t.isHelper === params.isHelper);
139
+ }
140
+ return filtered;
141
+ }
142
+ /**
143
+ * Форматировать результаты по уровню детализации
144
+ */
145
+ formatResults(results, detailLevel) {
146
+ const index = this.getIndex();
147
+ return results.map((r) => {
148
+ const staticData = index.find((t) => t.name === r.toolName);
149
+ if (!staticData) {
150
+ // Не должно произойти, но на всякий случай
151
+ return { name: r.toolName };
152
+ }
153
+ switch (detailLevel) {
154
+ case 'name_only':
155
+ return {
156
+ name: staticData.name,
157
+ };
158
+ case 'name_and_description':
159
+ return {
160
+ name: staticData.name,
161
+ description: staticData.descriptionShort,
162
+ category: staticData.category,
163
+ score: Math.round(r.score * 100) / 100, // 2 decimal places
164
+ };
165
+ case 'full': {
166
+ // Lazy load полных метаданных из ToolRegistry
167
+ const tool = this.toolRegistry.getTool(staticData.name);
168
+ const fullMetadata = tool?.getMetadata();
169
+ return {
170
+ name: staticData.name,
171
+ description: fullMetadata?.definition.description || staticData.descriptionShort,
172
+ category: staticData.category,
173
+ tags: staticData.tags,
174
+ inputSchema: fullMetadata?.definition.inputSchema,
175
+ examples: fullMetadata?.examples,
176
+ score: Math.round(r.score * 100) / 100,
177
+ matchDetails: r.matchDetails,
178
+ };
179
+ }
180
+ }
181
+ });
182
+ }
183
+ /**
184
+ * Генерировать ключ кеша из параметров поиска
185
+ */
186
+ getCacheKey(params) {
187
+ return JSON.stringify({
188
+ q: params.query.toLowerCase().trim(),
189
+ c: params.category,
190
+ h: params.isHelper,
191
+ l: params.limit,
192
+ d: params.detailLevel || 'name_and_description',
193
+ });
194
+ }
195
+ /**
196
+ * Очистить кеш
197
+ *
198
+ * Полезно для тестов и при обновлении индекса
199
+ */
200
+ clearCache() {
201
+ this.cache.clear();
202
+ }
203
+ /**
204
+ * Получить статистику кеша
205
+ */
206
+ getCacheStats() {
207
+ return {
208
+ size: this.cache.size,
209
+ maxSize: this.MAX_CACHE_SIZE,
210
+ };
211
+ }
212
+ }
213
+ //# sourceMappingURL=tool-search-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-search-engine.js","sourceRoot":"","sources":["../../src/engine/tool-search-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Модуль поиска tools
3
+ *
4
+ * Экспортирует:
5
+ * - Типы для поиска
6
+ * - Стратегии поиска
7
+ * - Поисковый движок
8
+ * - Веса стратегий
9
+ */
10
+ export type { StaticToolIndex, SearchResult, SearchParams, SearchResponse, ToolSearchResultItem, StrategyType, DetailLevel, } from './types.js';
11
+ export { STRATEGY_WEIGHTS } from './scoring/strategy-weights.js';
12
+ export type { ISearchStrategy } from './strategies/index.js';
13
+ export { NameSearchStrategy, DescriptionSearchStrategy, CategorySearchStrategy, FuzzySearchStrategy, WeightedCombinedStrategy, } from './strategies/index.js';
14
+ export { ToolSearchEngine } from './engine/tool-search-engine.js';
15
+ export * from './tools/search-tools.tool.js';
16
+ export * from './tools/search-tools.definition.js';
17
+ export * from './tools/search-tools.schema.js';
18
+ export * from './constants.js';
19
+ export { buildIndexFromRegistry } from './utils/build-index-from-registry.js';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,YAAY,EACV,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,oBAAoB,EACpB,YAAY,EACZ,WAAW,GACZ,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAGjE,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,sBAAsB,EACtB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAGlE,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oCAAoC,CAAC;AACnD,cAAc,gCAAgC,CAAC;AAG/C,cAAc,gBAAgB,CAAC;AAG/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Модуль поиска tools
3
+ *
4
+ * Экспортирует:
5
+ * - Типы для поиска
6
+ * - Стратегии поиска
7
+ * - Поисковый движок
8
+ * - Веса стратегий
9
+ */
10
+ // Веса
11
+ export { STRATEGY_WEIGHTS } from './scoring/strategy-weights.js';
12
+ export { NameSearchStrategy, DescriptionSearchStrategy, CategorySearchStrategy, FuzzySearchStrategy, WeightedCombinedStrategy, } from './strategies/index.js';
13
+ // Поисковый движок
14
+ export { ToolSearchEngine } from './engine/tool-search-engine.js';
15
+ // Tools (SearchToolsTool)
16
+ export * from './tools/search-tools.tool.js';
17
+ export * from './tools/search-tools.definition.js';
18
+ export * from './tools/search-tools.schema.js';
19
+ // Constants
20
+ export * from './constants.js';
21
+ // Dynamic index builder
22
+ export { buildIndexFromRegistry } from './utils/build-index-from-registry.js';
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,OAAO;AACP,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAIjE,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,sBAAsB,EACtB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAE/B,mBAAmB;AACnB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAElE,0BAA0B;AAC1B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oCAAoC,CAAC;AACnD,cAAc,gCAAgC,CAAC;AAE/C,YAAY;AACZ,cAAc,gBAAgB,CAAC;AAE/B,wBAAwB;AACxB,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Веса стратегий поиска
3
+ *
4
+ * Определяют важность каждого типа совпадения в финальном score
5
+ *
6
+ * Responsibilities:
7
+ * - Конфигурация весов для разных типов поиска
8
+ * - Балансировка между точностью и полнотой
9
+ */
10
+ import type { StrategyType } from '../types.js';
11
+ /**
12
+ * Веса стратегий поиска
13
+ *
14
+ * Значения (0-1):
15
+ * - 1.0 - максимальный вес (наиболее релевантно)
16
+ * - 0.5 - средний вес
17
+ * - 0.3 - минимальный вес (для дополнительных совпадений)
18
+ */
19
+ export declare const STRATEGY_WEIGHTS: Record<StrategyType, number>;
20
+ //# sourceMappingURL=strategy-weights.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy-weights.d.ts","sourceRoot":"","sources":["../../src/scoring/strategy-weights.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAoChD,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Веса стратегий поиска
3
+ *
4
+ * Определяют важность каждого типа совпадения в финальном score
5
+ *
6
+ * Responsibilities:
7
+ * - Конфигурация весов для разных типов поиска
8
+ * - Балансировка между точностью и полнотой
9
+ */
10
+ /**
11
+ * Веса стратегий поиска
12
+ *
13
+ * Значения (0-1):
14
+ * - 1.0 - максимальный вес (наиболее релевантно)
15
+ * - 0.5 - средний вес
16
+ * - 0.3 - минимальный вес (для дополнительных совпадений)
17
+ */
18
+ export const STRATEGY_WEIGHTS = {
19
+ /**
20
+ * Совпадение по имени — максимальный приоритет
21
+ *
22
+ * Примеры: "get_issues", "ping", "find_issues"
23
+ */
24
+ name: 1.0,
25
+ /**
26
+ * Совпадение по категории — высокий приоритет
27
+ *
28
+ * Примеры: category="issues", category="users"
29
+ */
30
+ category: 0.9,
31
+ /**
32
+ * Совпадение по тегам — средний приоритет
33
+ *
34
+ * Примеры: tags=["batch", "read"], tags=["helper"]
35
+ */
36
+ tags: 0.7,
37
+ /**
38
+ * Совпадение в описании — низкий приоритет
39
+ *
40
+ * Может содержать много noise (общие слова)
41
+ */
42
+ description: 0.5,
43
+ /**
44
+ * Fuzzy match — минимальный приоритет
45
+ *
46
+ * Для опечаток и приблизительных совпадений
47
+ * Примеры: "get_isseu" → "get_issues"
48
+ */
49
+ fuzzy: 0.3,
50
+ };
51
+ //# sourceMappingURL=strategy-weights.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy-weights.js","sourceRoot":"","sources":["../../src/scoring/strategy-weights.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAiC;IAC5D;;;;OAIG;IACH,IAAI,EAAE,GAAG;IAET;;;;OAIG;IACH,QAAQ,EAAE,GAAG;IAEb;;;;OAIG;IACH,IAAI,EAAE,GAAG;IAET;;;;OAIG;IACH,WAAW,EAAE,GAAG;IAEhB;;;;;OAKG;IACH,KAAK,EAAE,GAAG;CACF,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Стратегия поиска по категориям и тегам
3
+ *
4
+ * Алгоритм:
5
+ * - Точное совпадение категории: score = 1.0
6
+ * - Совпадение тега: score = 0.9
7
+ * - Частичное совпадение тега: score = 0.7
8
+ *
9
+ * Responsibilities:
10
+ * - Поиск по категориям
11
+ * - Поиск по тегам
12
+ * - Оценка релевантности совпадения
13
+ */
14
+ import type { ISearchStrategy } from './search-strategy.interface.js';
15
+ import type { SearchResult, StaticToolIndex } from '../types.js';
16
+ /**
17
+ * Стратегия поиска по категориям и тегам
18
+ */
19
+ export declare class CategorySearchStrategy implements ISearchStrategy {
20
+ search(query: string, tools: StaticToolIndex[]): SearchResult[];
21
+ /**
22
+ * Оценка совпадения с категорией
23
+ */
24
+ private scoreCategoryMatch;
25
+ /**
26
+ * Найти совпадение в тегах
27
+ */
28
+ private findTagMatch;
29
+ }
30
+ //# sourceMappingURL=category-search.strategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"category-search.strategy.d.ts","sourceRoot":"","sources":["../../src/strategies/category-search.strategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEjE;;GAEG;AACH,qBAAa,sBAAuB,YAAW,eAAe;IAC5D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,YAAY,EAAE;IAqC/D;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAc1B;;OAEG;IACH,OAAO,CAAC,YAAY;CAmBrB"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Стратегия поиска по категориям и тегам
3
+ *
4
+ * Алгоритм:
5
+ * - Точное совпадение категории: score = 1.0
6
+ * - Совпадение тега: score = 0.9
7
+ * - Частичное совпадение тега: score = 0.7
8
+ *
9
+ * Responsibilities:
10
+ * - Поиск по категориям
11
+ * - Поиск по тегам
12
+ * - Оценка релевантности совпадения
13
+ */
14
+ /**
15
+ * Стратегия поиска по категориям и тегам
16
+ */
17
+ export class CategorySearchStrategy {
18
+ search(query, tools) {
19
+ const lowerQuery = query.toLowerCase().trim();
20
+ if (!lowerQuery) {
21
+ return [];
22
+ }
23
+ const results = [];
24
+ for (const tool of tools) {
25
+ // Проверка категории
26
+ const categoryScore = this.scoreCategoryMatch(tool.category, lowerQuery);
27
+ if (categoryScore > 0) {
28
+ results.push({
29
+ toolName: tool.name,
30
+ score: categoryScore,
31
+ matchReason: `Category match: ${tool.category}`,
32
+ strategyType: 'category',
33
+ });
34
+ continue; // Если нашли в категории, не проверяем теги
35
+ }
36
+ // Проверка тегов
37
+ const tagMatch = this.findTagMatch(tool.tags, lowerQuery);
38
+ if (tagMatch) {
39
+ results.push({
40
+ toolName: tool.name,
41
+ score: tagMatch.score,
42
+ matchReason: `Tag match: ${tagMatch.tag}`,
43
+ strategyType: 'tags',
44
+ });
45
+ }
46
+ }
47
+ return results;
48
+ }
49
+ /**
50
+ * Оценка совпадения с категорией
51
+ */
52
+ scoreCategoryMatch(category, query) {
53
+ const lowerCategory = category.toLowerCase();
54
+ if (lowerCategory === query) {
55
+ return 1.0; // Точное совпадение
56
+ }
57
+ if (lowerCategory.includes(query) || query.includes(lowerCategory)) {
58
+ return 0.8; // Частичное совпадение
59
+ }
60
+ return 0;
61
+ }
62
+ /**
63
+ * Найти совпадение в тегах
64
+ */
65
+ findTagMatch(tags, query) {
66
+ for (const tag of tags) {
67
+ const lowerTag = tag.toLowerCase();
68
+ if (lowerTag === query) {
69
+ return { tag, score: 0.9 }; // Точное совпадение тега
70
+ }
71
+ if (lowerTag.includes(query)) {
72
+ return { tag, score: 0.7 }; // Частичное совпадение тега
73
+ }
74
+ if (query.includes(lowerTag)) {
75
+ return { tag, score: 0.6 }; // Query содержит тег
76
+ }
77
+ }
78
+ return undefined;
79
+ }
80
+ }
81
+ //# sourceMappingURL=category-search.strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"category-search.strategy.js","sourceRoot":"","sources":["../../src/strategies/category-search.strategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH;;GAEG;AACH,MAAM,OAAO,sBAAsB;IACjC,MAAM,CAAC,KAAa,EAAE,KAAwB;QAC5C,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;QAE9C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,OAAO,GAAmB,EAAE,CAAC;QAEnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,qBAAqB;YACrB,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YACzE,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;gBACtB,OAAO,CAAC,IAAI,CAAC;oBACX,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,KAAK,EAAE,aAAa;oBACpB,WAAW,EAAE,mBAAmB,IAAI,CAAC,QAAQ,EAAE;oBAC/C,YAAY,EAAE,UAAU;iBACzB,CAAC,CAAC;gBACH,SAAS,CAAC,4CAA4C;YACxD,CAAC;YAED,iBAAiB;YACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YAC1D,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC;oBACX,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,KAAK,EAAE,QAAQ,CAAC,KAAK;oBACrB,WAAW,EAAE,cAAc,QAAQ,CAAC,GAAG,EAAE;oBACzC,YAAY,EAAE,MAAM;iBACrB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,QAAgB,EAAE,KAAa;QACxD,MAAM,aAAa,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QAE7C,IAAI,aAAa,KAAK,KAAK,EAAE,CAAC;YAC5B,OAAO,GAAG,CAAC,CAAC,oBAAoB;QAClC,CAAC;QAED,IAAI,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YACnE,OAAO,GAAG,CAAC,CAAC,uBAAuB;QACrC,CAAC;QAED,OAAO,CAAC,CAAC;IACX,CAAC;IAED;;OAEG;IACK,YAAY,CAAC,IAAc,EAAE,KAAa;QAChD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;YAEnC,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;gBACvB,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,yBAAyB;YACvD,CAAC;YAED,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC7B,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,4BAA4B;YAC1D,CAAC;YAED,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,qBAAqB;YACnD,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;CACF"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Стратегия full-text поиска по описанию
3
+ *
4
+ * Алгоритм:
5
+ * - Токенизация query и description
6
+ * - Подсчёт совпадающих токенов
7
+ * - Score = (matched tokens) / (total query tokens) * weight
8
+ *
9
+ * Responsibilities:
10
+ * - Полнотекстовый поиск по описанию
11
+ * - Токенизация текста
12
+ * - Оценка релевантности по количеству совпадений
13
+ */
14
+ import type { ISearchStrategy } from './search-strategy.interface.js';
15
+ import type { SearchResult, StaticToolIndex } from '../types.js';
16
+ /**
17
+ * Стратегия поиска по описанию
18
+ */
19
+ export declare class DescriptionSearchStrategy implements ISearchStrategy {
20
+ /**
21
+ * Минимальная длина токена для поиска
22
+ *
23
+ * Игнорируем короткие слова (предлоги, союзы и т.д.)
24
+ */
25
+ private readonly MIN_TOKEN_LENGTH;
26
+ /**
27
+ * Вес для description search
28
+ *
29
+ * Пониженный, т.к. description может содержать много noise
30
+ */
31
+ private readonly DESCRIPTION_WEIGHT;
32
+ search(query: string, tools: StaticToolIndex[]): SearchResult[];
33
+ /**
34
+ * Найти совпадающие токены
35
+ */
36
+ private findMatches;
37
+ }
38
+ //# sourceMappingURL=description-search.strategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"description-search.strategy.d.ts","sourceRoot":"","sources":["../../src/strategies/description-search.strategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGjE;;GAEG;AACH,qBAAa,yBAA0B,YAAW,eAAe;IAC/D;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAK;IAEtC;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAO;IAE1C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,YAAY,EAAE;IA8B/D;;OAEG;IACH,OAAO,CAAC,WAAW;CAgBpB"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Стратегия full-text поиска по описанию
3
+ *
4
+ * Алгоритм:
5
+ * - Токенизация query и description
6
+ * - Подсчёт совпадающих токенов
7
+ * - Score = (matched tokens) / (total query tokens) * weight
8
+ *
9
+ * Responsibilities:
10
+ * - Полнотекстовый поиск по описанию
11
+ * - Токенизация текста
12
+ * - Оценка релевантности по количеству совпадений
13
+ */
14
+ import { tokenize } from '../utils/text-utils.js';
15
+ /**
16
+ * Стратегия поиска по описанию
17
+ */
18
+ export class DescriptionSearchStrategy {
19
+ /**
20
+ * Минимальная длина токена для поиска
21
+ *
22
+ * Игнорируем короткие слова (предлоги, союзы и т.д.)
23
+ */
24
+ MIN_TOKEN_LENGTH = 2;
25
+ /**
26
+ * Вес для description search
27
+ *
28
+ * Пониженный, т.к. description может содержать много noise
29
+ */
30
+ DESCRIPTION_WEIGHT = 0.7;
31
+ search(query, tools) {
32
+ const queryTokens = tokenize(query, {
33
+ normalizeSeparators: false,
34
+ minLength: this.MIN_TOKEN_LENGTH,
35
+ });
36
+ if (queryTokens.length === 0) {
37
+ return [];
38
+ }
39
+ const results = [];
40
+ for (const tool of tools) {
41
+ const matches = this.findMatches(queryTokens, tool.descriptionTokens);
42
+ if (matches.length > 0) {
43
+ const score = (matches.length / queryTokens.length) * this.DESCRIPTION_WEIGHT;
44
+ results.push({
45
+ toolName: tool.name,
46
+ score,
47
+ matchReason: `Matched ${matches.length}/${queryTokens.length} tokens in description`,
48
+ strategyType: 'description',
49
+ });
50
+ }
51
+ }
52
+ return results;
53
+ }
54
+ /**
55
+ * Найти совпадающие токены
56
+ */
57
+ findMatches(queryTokens, descTokens) {
58
+ const matches = [];
59
+ for (const queryToken of queryTokens) {
60
+ const found = descTokens.some((descToken) => descToken.includes(queryToken) || queryToken.includes(descToken));
61
+ if (found) {
62
+ matches.push(queryToken);
63
+ }
64
+ }
65
+ return matches;
66
+ }
67
+ }
68
+ //# sourceMappingURL=description-search.strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"description-search.strategy.js","sourceRoot":"","sources":["../../src/strategies/description-search.strategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD;;GAEG;AACH,MAAM,OAAO,yBAAyB;IACpC;;;;OAIG;IACc,gBAAgB,GAAG,CAAC,CAAC;IAEtC;;;;OAIG;IACc,kBAAkB,GAAG,GAAG,CAAC;IAE1C,MAAM,CAAC,KAAa,EAAE,KAAwB;QAC5C,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,EAAE;YAClC,mBAAmB,EAAE,KAAK;YAC1B,SAAS,EAAE,IAAI,CAAC,gBAAgB;SACjC,CAAC,CAAC;QAEH,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,OAAO,GAAmB,EAAE,CAAC;QAEnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAEtE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,kBAAkB,CAAC;gBAE9E,OAAO,CAAC,IAAI,CAAC;oBACX,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,KAAK;oBACL,WAAW,EAAE,WAAW,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC,MAAM,wBAAwB;oBACpF,YAAY,EAAE,aAAa;iBAC5B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,WAAqB,EAAE,UAAoB;QAC7D,MAAM,OAAO,GAAa,EAAE,CAAC;QAE7B,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAC3B,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAChF,CAAC;YAEF,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CAEF"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Стратегия fuzzy поиска с использованием Levenshtein distance
3
+ *
4
+ * Алгоритм:
5
+ * - Вычисление Levenshtein distance между query и именем
6
+ * - Score уменьшается с ростом distance
7
+ * - Поиск в имени и токенах
8
+ *
9
+ * Полезно для:
10
+ * - Опечатки (get_isseu → get_issues)
11
+ * - Частичные совпадения (get_iss → get_issues)
12
+ *
13
+ * Responsibilities:
14
+ * - Fuzzy matching с допустимой погрешностью
15
+ * - Вычисление Levenshtein distance
16
+ * - Оценка релевантности с учётом distance
17
+ */
18
+ import type { ISearchStrategy } from './search-strategy.interface.js';
19
+ import type { SearchResult, StaticToolIndex } from '../types.js';
20
+ /**
21
+ * Стратегия fuzzy поиска
22
+ */
23
+ export declare class FuzzySearchStrategy implements ISearchStrategy {
24
+ /**
25
+ * Максимальная допустимая distance
26
+ *
27
+ * distance = количество операций (insert/delete/replace)
28
+ * для преобразования одной строки в другую
29
+ */
30
+ private readonly maxDistance;
31
+ /**
32
+ * Вес для token matches
33
+ *
34
+ * Поиск в токенах менее точен, чем в полном имени
35
+ */
36
+ private readonly TOKEN_WEIGHT;
37
+ constructor(maxDistance?: number);
38
+ search(query: string, tools: StaticToolIndex[]): SearchResult[];
39
+ /**
40
+ * Найти fuzzy match в токенах
41
+ */
42
+ private findTokenMatch;
43
+ /**
44
+ * Вычислить score на основе distance
45
+ *
46
+ * Score уменьшается линейно с ростом distance:
47
+ * - distance = 0 → score = 1.0
48
+ * - distance = maxDistance → score ≈ 0
49
+ */
50
+ private calculateScore;
51
+ /**
52
+ * Levenshtein distance algorithm
53
+ *
54
+ * Вычисляет минимальное количество операций (insert/delete/replace)
55
+ * для преобразования одной строки в другую
56
+ *
57
+ * Complexity: O(m * n), где m и n - длины строк
58
+ *
59
+ * @param a - первая строка
60
+ * @param b - вторая строка
61
+ * @returns количество операций редактирования
62
+ */
63
+ private levenshteinDistance;
64
+ }
65
+ //# sourceMappingURL=fuzzy-search.strategy.d.ts.map