@elliotding/ai-agent-mcp 0.2.0 → 0.2.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.
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Search Coordinator
3
+ * Orchestrates Tier 1 + Tier 2 search and merges results
4
+ */
5
+ import type { ResourceCandidate, ScoredResult } from './tier1-keyword-match';
6
+ export declare class SearchCoordinator {
7
+ private tier1;
8
+ private tier2;
9
+ constructor();
10
+ /**
11
+ * Merge results from multiple tiers (dedup + keep highest score)
12
+ */
13
+ private mergeResults;
14
+ /**
15
+ * Execute enhanced search (two-tier architecture)
16
+ *
17
+ * Strategy:
18
+ * 1. Tier 1: Precise keyword matching
19
+ * 2. If Tier 1 has enough high-quality results (≥3 and top score ≥70), return directly
20
+ * 3. Otherwise, run Tier 2 fuzzy search to supplement
21
+ * 4. Merge and deduplicate
22
+ * 5. Filter very low scores (< 20)
23
+ */
24
+ enhancedSearch(query: string, apiResults: ResourceCandidate[], maxResults?: number): ScoredResult[];
25
+ }
26
+ //# sourceMappingURL=coordinator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinator.d.ts","sourceRoot":"","sources":["../../src/search/coordinator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE7E,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,KAAK,CAAgB;;IAO7B;;OAEG;IACH,OAAO,CAAC,YAAY;IA6BpB;;;;;;;;;OASG;IACH,cAAc,CACZ,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,iBAAiB,EAAE,EAC/B,UAAU,GAAE,MAAW,GACtB,YAAY,EAAE;CAwClB"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ /**
3
+ * Search Coordinator
4
+ * Orchestrates Tier 1 + Tier 2 search and merges results
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.SearchCoordinator = void 0;
8
+ const logger_1 = require("../utils/logger");
9
+ const tier1_keyword_match_1 = require("./tier1-keyword-match");
10
+ const tier2_fuzzy_search_1 = require("./tier2-fuzzy-search");
11
+ class SearchCoordinator {
12
+ tier1;
13
+ tier2;
14
+ constructor() {
15
+ this.tier1 = new tier1_keyword_match_1.KeywordMatcher();
16
+ this.tier2 = new tier2_fuzzy_search_1.FuzzySearcher();
17
+ }
18
+ /**
19
+ * Merge results from multiple tiers (dedup + keep highest score)
20
+ */
21
+ mergeResults(resultSets) {
22
+ const resultMap = new Map(); // key: resource.id
23
+ for (const results of resultSets) {
24
+ for (const result of results) {
25
+ const existing = resultMap.get(result.id);
26
+ if (existing) {
27
+ // Keep higher score, same score prefer lower tier (higher priority)
28
+ if (result.score > existing.score ||
29
+ (result.score === existing.score && result.match_tier < existing.match_tier)) {
30
+ resultMap.set(result.id, result);
31
+ }
32
+ }
33
+ else {
34
+ resultMap.set(result.id, result);
35
+ }
36
+ }
37
+ }
38
+ // Sort: score desc → tier asc → name alpha
39
+ return Array.from(resultMap.values()).sort((a, b) => {
40
+ if (a.score !== b.score)
41
+ return b.score - a.score;
42
+ if (a.match_tier !== b.match_tier)
43
+ return a.match_tier - b.match_tier;
44
+ return a.name.localeCompare(b.name);
45
+ });
46
+ }
47
+ /**
48
+ * Execute enhanced search (two-tier architecture)
49
+ *
50
+ * Strategy:
51
+ * 1. Tier 1: Precise keyword matching
52
+ * 2. If Tier 1 has enough high-quality results (≥3 and top score ≥70), return directly
53
+ * 3. Otherwise, run Tier 2 fuzzy search to supplement
54
+ * 4. Merge and deduplicate
55
+ * 5. Filter very low scores (< 20)
56
+ */
57
+ enhancedSearch(query, apiResults, maxResults = 10) {
58
+ logger_1.logger.info({ query, candidateCount: apiResults.length }, 'Enhanced search started');
59
+ // 1. Tier 1: Precise keyword matching
60
+ const tier1Results = this.tier1.search(query, apiResults);
61
+ // Filter low scores immediately
62
+ const tier1Filtered = tier1Results.filter((r) => r.score >= 20);
63
+ // If Tier 1 has enough high-quality results, return directly
64
+ if (tier1Filtered.length >= 3 && tier1Filtered[0] && tier1Filtered[0].score >= 70) {
65
+ logger_1.logger.info({ tier1Count: tier1Filtered.length, topScore: tier1Filtered[0].score }, 'Tier 1 sufficient, skipping Tier 2');
66
+ return tier1Filtered.slice(0, maxResults);
67
+ }
68
+ // 2. Tier 2: Fuzzy search to supplement
69
+ const tier2Results = this.tier2.search(query, apiResults);
70
+ // 3. Merge and deduplicate
71
+ const merged = this.mergeResults([tier1Filtered, tier2Results]);
72
+ // 4. Filter very low scores (< 20) and limit count
73
+ const filtered = merged.filter((r) => r.score >= 20).slice(0, maxResults);
74
+ logger_1.logger.info({
75
+ tier1Count: tier1Filtered.length,
76
+ tier2Count: tier2Results.length,
77
+ mergedCount: merged.length,
78
+ finalCount: filtered.length,
79
+ topScore: filtered.length > 0 && filtered[0] ? filtered[0].score : undefined,
80
+ }, 'Enhanced search completed');
81
+ return filtered;
82
+ }
83
+ }
84
+ exports.SearchCoordinator = SearchCoordinator;
85
+ //# sourceMappingURL=coordinator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinator.js","sourceRoot":"","sources":["../../src/search/coordinator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Search Module Exports
3
+ */
4
+ export { SearchCoordinator } from './coordinator';
5
+ export { KeywordMatcher } from './tier1-keyword-match';
6
+ export { FuzzySearcher } from './tier2-fuzzy-search';
7
+ export type { ResourceCandidate, ScoredResult } from './tier1-keyword-match';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/search/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ /**
3
+ * Search Module Exports
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FuzzySearcher = exports.KeywordMatcher = exports.SearchCoordinator = void 0;
7
+ var coordinator_1 = require("./coordinator");
8
+ Object.defineProperty(exports, "SearchCoordinator", { enumerable: true, get: function () { return coordinator_1.SearchCoordinator; } });
9
+ var tier1_keyword_match_1 = require("./tier1-keyword-match");
10
+ Object.defineProperty(exports, "KeywordMatcher", { enumerable: true, get: function () { return tier1_keyword_match_1.KeywordMatcher; } });
11
+ var tier2_fuzzy_search_1 = require("./tier2-fuzzy-search");
12
+ Object.defineProperty(exports, "FuzzySearcher", { enumerable: true, get: function () { return tier2_fuzzy_search_1.FuzzySearcher; } });
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/search/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,6CAAkD;AAAzC,gHAAA,iBAAiB,OAAA;AAC1B,6DAAuD;AAA9C,qHAAA,cAAc,OAAA;AACvB,2DAAqD;AAA5C,mHAAA,aAAa,OAAA"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Tier 1: Keyword Matcher
3
+ * Precise keyword matching with weighted scoring (name > description)
4
+ */
5
+ export interface ResourceCandidate {
6
+ id: string;
7
+ name: string;
8
+ description: string;
9
+ type: string;
10
+ team: string;
11
+ version: string;
12
+ is_subscribed: boolean;
13
+ download_url?: string;
14
+ metadata?: unknown;
15
+ }
16
+ export interface ScoredResult extends ResourceCandidate {
17
+ score: number;
18
+ match_tier: 1 | 2;
19
+ match_reason: string;
20
+ excerpt?: string;
21
+ }
22
+ export declare class KeywordMatcher {
23
+ private readonly STOP_WORDS;
24
+ /**
25
+ * Extract keywords from query (supports Chinese and English)
26
+ */
27
+ private extractKeywords;
28
+ /**
29
+ * Escape special regex characters
30
+ */
31
+ private escapeRegex;
32
+ /**
33
+ * Calculate match score with weighted fields
34
+ *
35
+ * Scoring rules:
36
+ * - name field weight: 3x
37
+ * - description field weight: 1x
38
+ * - Whole word match > partial match
39
+ * - If name doesn't match at all, force 70% penalty
40
+ */
41
+ private calculateScore;
42
+ /**
43
+ * Build human-readable match reason
44
+ */
45
+ private buildMatchReason;
46
+ /**
47
+ * Execute Tier 1 search
48
+ */
49
+ search(query: string, candidates: ResourceCandidate[]): ScoredResult[];
50
+ }
51
+ //# sourceMappingURL=tier1-keyword-match.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier1-keyword-match.d.ts","sourceRoot":"","sources":["../../src/search/tier1-keyword-match.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAa,SAAQ,iBAAiB;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAOxB;IAEH;;OAEG;IACH,OAAO,CAAC,eAAe;IAYvB;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;;;;;;;OAQG;IACH,OAAO,CAAC,cAAc;IA6CtB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAmBxB;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,EAAE,GAAG,YAAY,EAAE;CAgCvE"}
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ /**
3
+ * Tier 1: Keyword Matcher
4
+ * Precise keyword matching with weighted scoring (name > description)
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.KeywordMatcher = void 0;
8
+ const logger_1 = require("../utils/logger");
9
+ class KeywordMatcher {
10
+ STOP_WORDS = new Set([
11
+ // English stop words
12
+ 'a', 'an', 'and', 'are', 'as', 'at', 'be', 'by', 'for', 'from',
13
+ 'has', 'he', 'in', 'is', 'it', 'its', 'of', 'on', 'that', 'the',
14
+ 'to', 'was', 'will', 'with',
15
+ // Chinese stop words
16
+ '的', '是', '在', '和', '了', '有', '与', '这', '个', '我',
17
+ ]);
18
+ /**
19
+ * Extract keywords from query (supports Chinese and English)
20
+ */
21
+ extractKeywords(query) {
22
+ // Split by spaces, underscores, hyphens, and Chinese characters
23
+ const words = query
24
+ .toLowerCase()
25
+ .split(/[\s_\-]+/)
26
+ .map((w) => w.trim())
27
+ .filter((w) => w.length > 0);
28
+ // Filter out stop words
29
+ return words.filter((w) => !this.STOP_WORDS.has(w));
30
+ }
31
+ /**
32
+ * Escape special regex characters
33
+ */
34
+ escapeRegex(str) {
35
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
36
+ }
37
+ /**
38
+ * Calculate match score with weighted fields
39
+ *
40
+ * Scoring rules:
41
+ * - name field weight: 3x
42
+ * - description field weight: 1x
43
+ * - Whole word match > partial match
44
+ * - If name doesn't match at all, force 70% penalty
45
+ */
46
+ calculateScore(keywords, resource) {
47
+ const lowerName = resource.name.toLowerCase();
48
+ const lowerDesc = resource.description.toLowerCase();
49
+ let nameMatchCount = 0;
50
+ let descMatchCount = 0;
51
+ for (const keyword of keywords) {
52
+ // Prefer whole word matching (using regex \b boundary)
53
+ const wordBoundaryRegex = new RegExp(`\\b${this.escapeRegex(keyword)}\\b`, 'i');
54
+ if (wordBoundaryRegex.test(resource.name)) {
55
+ nameMatchCount++;
56
+ }
57
+ else if (lowerName.includes(keyword)) {
58
+ nameMatchCount += 0.7; // Partial match penalty
59
+ }
60
+ if (wordBoundaryRegex.test(resource.description)) {
61
+ descMatchCount++;
62
+ }
63
+ else if (lowerDesc.includes(keyword)) {
64
+ descMatchCount += 0.5; // Description partial match penalty
65
+ }
66
+ }
67
+ // ✅ Critical rule: If name doesn't match at all, force penalty
68
+ if (nameMatchCount === 0 && descMatchCount > 0) {
69
+ // Description matches but name doesn't, only give 30% of base score
70
+ // This ensures resources like "release-log-review" (only mentions "build info" in description)
71
+ // don't get high scores (e.g., 25 → 7)
72
+ const baseScore = (descMatchCount * 1) / keywords.length * 25;
73
+ return Math.floor(baseScore * 0.3); // Force 70% penalty
74
+ }
75
+ // Name has matches, calculate normally
76
+ const weightedScore = (nameMatchCount * 3 + descMatchCount * 1) / keywords.length;
77
+ let score = Math.floor(weightedScore * 25); // Map to 0-100
78
+ // Bonus: All keywords match in name
79
+ if (nameMatchCount >= keywords.length && keywords.length > 1) {
80
+ score = Math.min(100, score + 20);
81
+ }
82
+ return score;
83
+ }
84
+ /**
85
+ * Build human-readable match reason
86
+ */
87
+ buildMatchReason(keywords, resource) {
88
+ const lowerName = resource.name.toLowerCase();
89
+ const lowerDesc = resource.description.toLowerCase();
90
+ const nameMatches = keywords.filter((k) => lowerName.includes(k));
91
+ const descMatches = keywords.filter((k) => lowerDesc.includes(k) && !lowerName.includes(k));
92
+ if (nameMatches.length === keywords.length) {
93
+ return `Name matches all keywords: ${nameMatches.join(', ')}`;
94
+ }
95
+ if (nameMatches.length > 0) {
96
+ return `Name matches: ${nameMatches.join(', ')}`;
97
+ }
98
+ if (descMatches.length > 0) {
99
+ return `Description matches: ${descMatches.join(', ')}`;
100
+ }
101
+ return 'No keyword match';
102
+ }
103
+ /**
104
+ * Execute Tier 1 search
105
+ */
106
+ search(query, candidates) {
107
+ const keywords = this.extractKeywords(query);
108
+ if (keywords.length === 0) {
109
+ logger_1.logger.debug({ query }, 'No valid keywords extracted');
110
+ return [];
111
+ }
112
+ logger_1.logger.debug({ query, keywords }, 'Tier 1 keyword search started');
113
+ const results = [];
114
+ for (const resource of candidates) {
115
+ const score = this.calculateScore(keywords, resource);
116
+ if (score > 0) {
117
+ results.push({
118
+ ...resource,
119
+ score,
120
+ match_tier: 1,
121
+ match_reason: this.buildMatchReason(keywords, resource),
122
+ });
123
+ }
124
+ }
125
+ // Sort by score descending
126
+ const sorted = results.sort((a, b) => b.score - a.score);
127
+ logger_1.logger.debug({ resultCount: sorted.length, topScore: sorted[0]?.score }, 'Tier 1 search completed');
128
+ return sorted;
129
+ }
130
+ }
131
+ exports.KeywordMatcher = KeywordMatcher;
132
+ //# sourceMappingURL=tier1-keyword-match.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier1-keyword-match.js","sourceRoot":"","sources":["../../src/search/tier1-keyword-match.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Tier 2: Fuzzy Searcher
3
+ * Semantic fuzzy search powered by Fuse.js
4
+ */
5
+ import type { ResourceCandidate, ScoredResult } from './tier1-keyword-match';
6
+ export declare class FuzzySearcher {
7
+ private readonly fuseOptions;
8
+ /**
9
+ * Prepare searchable data structure
10
+ */
11
+ private prepareSearchableData;
12
+ /**
13
+ * Convert Fuse score (0=best) to normal score (100=best)
14
+ */
15
+ private convertFuseScore;
16
+ /**
17
+ * Extract excerpt (matched context)
18
+ */
19
+ private extractExcerpt;
20
+ /**
21
+ * Build match reason
22
+ */
23
+ private buildMatchReason;
24
+ /**
25
+ * Execute Tier 2 search
26
+ */
27
+ search(query: string, candidates: ResourceCandidate[]): ScoredResult[];
28
+ }
29
+ //# sourceMappingURL=tier2-fuzzy-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier2-fuzzy-search.d.ts","sourceRoot":"","sources":["../../src/search/tier2-fuzzy-search.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAM7E,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAY1B;IAEF;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;OAEG;IACH,OAAO,CAAC,cAAc;IAqBtB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAcxB;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,EAAE,GAAG,YAAY,EAAE;CA8BvE"}
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ /**
3
+ * Tier 2: Fuzzy Searcher
4
+ * Semantic fuzzy search powered by Fuse.js
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.FuzzySearcher = void 0;
11
+ const fuse_js_1 = __importDefault(require("fuse.js"));
12
+ const logger_1 = require("../utils/logger");
13
+ class FuzzySearcher {
14
+ fuseOptions = {
15
+ keys: [
16
+ { name: 'name', weight: 0.5 }, // name has highest weight
17
+ { name: 'description', weight: 0.3 }, // description second
18
+ { name: 'searchableContent', weight: 0.2 }, // combined content lowest
19
+ ],
20
+ threshold: 0.35, // Balanced threshold (0.3 too strict for Chinese, 0.4 too loose)
21
+ includeScore: true, // Return match scores
22
+ minMatchCharLength: 2, // Keep 2 for Chinese (Chinese chars are 2-3 bytes)
23
+ ignoreLocation: true, // Don't restrict match position
24
+ useExtendedSearch: false, // Don't need advanced query syntax
25
+ distance: 100, // Slightly relaxed for Chinese (was 50)
26
+ };
27
+ /**
28
+ * Prepare searchable data structure
29
+ */
30
+ prepareSearchableData(candidates) {
31
+ return candidates.map((resource) => ({
32
+ ...resource,
33
+ searchableContent: `${resource.name} ${resource.description}`,
34
+ }));
35
+ }
36
+ /**
37
+ * Convert Fuse score (0=best) to normal score (100=best)
38
+ */
39
+ convertFuseScore(fuseScore) {
40
+ const score = fuseScore ?? 0;
41
+ return Math.max(0, Math.min(100, Math.floor((1 - score) * 100)));
42
+ }
43
+ /**
44
+ * Extract excerpt (matched context)
45
+ */
46
+ extractExcerpt(text, query, maxLength = 150) {
47
+ const lowerText = text.toLowerCase();
48
+ const lowerQuery = query.toLowerCase();
49
+ const index = lowerText.indexOf(lowerQuery);
50
+ if (index === -1) {
51
+ // No exact match, return first 150 chars
52
+ return text.length > maxLength ? text.substring(0, maxLength) + '...' : text;
53
+ }
54
+ // Extract 50 chars before and after match
55
+ const start = Math.max(0, index - 50);
56
+ const end = Math.min(text.length, index + query.length + 50);
57
+ let excerpt = text.substring(start, end);
58
+ if (start > 0)
59
+ excerpt = '...' + excerpt;
60
+ if (end < text.length)
61
+ excerpt = excerpt + '...';
62
+ return excerpt;
63
+ }
64
+ /**
65
+ * Build match reason
66
+ */
67
+ buildMatchReason(query, resource) {
68
+ const lowerName = resource.name.toLowerCase();
69
+ const lowerDesc = resource.description.toLowerCase();
70
+ const lowerQuery = query.toLowerCase();
71
+ if (lowerName.includes(lowerQuery)) {
72
+ return `Name contains: "${query}"`;
73
+ }
74
+ if (lowerDesc.includes(lowerQuery)) {
75
+ return `Description mentions: "${query}"`;
76
+ }
77
+ return `Content semantically matches: "${query}"`;
78
+ }
79
+ /**
80
+ * Execute Tier 2 search
81
+ */
82
+ search(query, candidates) {
83
+ logger_1.logger.debug({ query, candidateCount: candidates.length }, 'Tier 2 fuzzy search started');
84
+ const searchableData = this.prepareSearchableData(candidates);
85
+ const fuse = new fuse_js_1.default(searchableData, this.fuseOptions);
86
+ const fuseResults = fuse.search(query);
87
+ const results = fuseResults.map((result) => {
88
+ const score = this.convertFuseScore(result.score);
89
+ const resource = result.item;
90
+ return {
91
+ ...resource,
92
+ score,
93
+ match_tier: 2,
94
+ match_reason: this.buildMatchReason(query, resource),
95
+ excerpt: this.extractExcerpt(resource.description, query),
96
+ };
97
+ });
98
+ // Filter low scores (< 40 for Tier 2, stricter than Tier 1)
99
+ const filtered = results.filter((r) => r.score >= 40);
100
+ logger_1.logger.debug({ resultCount: filtered.length, topScore: filtered[0]?.score }, 'Tier 2 search completed');
101
+ return filtered;
102
+ }
103
+ }
104
+ exports.FuzzySearcher = FuzzySearcher;
105
+ //# sourceMappingURL=tier2-fuzzy-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier2-fuzzy-search.js","sourceRoot":"","sources":["../../src/search/tier2-fuzzy-search.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"search-resources.d.ts","sourceRoot":"","sources":["../../src/tools/search-resources.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAyB,qBAAqB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AA8C/F,wBAAsB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,qBAAqB,CAAC,CAAC,CAgGjG;AAGD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6B/B,CAAC"}
1
+ {"version":3,"file":"search-resources.d.ts","sourceRoot":"","sources":["../../src/tools/search-resources.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAyB,qBAAqB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAmD/F,wBAAsB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,qBAAqB,CAAC,CAAC,CAkHjG;AAGD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6B/B,CAAC"}
@@ -11,6 +11,9 @@ const client_1 = require("../api/client");
11
11
  const manager_1 = require("../filesystem/manager");
12
12
  const cursor_paths_js_1 = require("../utils/cursor-paths.js");
13
13
  const errors_1 = require("../types/errors");
14
+ const search_1 = require("../search");
15
+ // Search coordinator singleton
16
+ const searchCoordinator = new search_1.SearchCoordinator();
14
17
  // Simple in-memory cache
15
18
  const searchCache = new Map();
16
19
  const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
@@ -76,8 +79,17 @@ async function searchResources(params) {
76
79
  type: typedParams.type,
77
80
  keyword: typedParams.keyword,
78
81
  }, typedParams.user_token);
82
+ // ✅ MCP Server-side enhanced search (Tier 1 + Tier 2)
83
+ logger_1.logger.debug({ apiResultCount: searchResults.results.length }, 'Applying MCP-side search enhancement...');
84
+ const enhancedResults = searchCoordinator.enhancedSearch(typedParams.keyword || '', searchResults.results, 20 // maxResults
85
+ );
86
+ logger_1.logger.info({
87
+ apiResults: searchResults.results.length,
88
+ enhancedResults: enhancedResults.length,
89
+ topScore: enhancedResults[0]?.score
90
+ }, 'Search enhancement applied');
79
91
  // Check subscription and installation status for each result
80
- const enhancedResults = await Promise.all(searchResults.results.map(async (resource) => {
92
+ const finalResults = await Promise.all(enhancedResults.map(async (resource) => {
81
93
  // Check if installed locally in the Cursor directory for this resource type
82
94
  let isInstalled = false;
83
95
  try {
@@ -95,8 +107,8 @@ async function searchResources(params) {
95
107
  }));
96
108
  // Build final result
97
109
  const result = {
98
- total: searchResults.total,
99
- results: enhancedResults,
110
+ total: finalResults.length,
111
+ results: finalResults,
100
112
  };
101
113
  // Cache the results
102
114
  cacheResults(cacheKey, result);
@@ -1 +1 @@
1
- {"version":3,"file":"search-resources.js","sourceRoot":"","sources":["../../src/tools/search-resources.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-resources.js","sourceRoot":"","sources":["../../src/tools/search-resources.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elliotding/ai-agent-mcp",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "CSP AI Agent MCP Server - Centralized AI tools distribution and management",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -43,6 +43,7 @@
43
43
  "axios": "^1.6.0",
44
44
  "dotenv": "^16.4.0",
45
45
  "fastify": "^5.8.2",
46
+ "fuse.js": "^7.1.0",
46
47
  "ioredis": "^5.10.0",
47
48
  "lru-cache": "^11.2.6",
48
49
  "pino": "^8.19.0",