@juspay/yama 1.6.0 → 2.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.
- package/.mcp-config.example.json +26 -0
- package/CHANGELOG.md +46 -0
- package/README.md +311 -685
- package/dist/cli/v2.cli.d.ts +13 -0
- package/dist/cli/v2.cli.js +359 -0
- package/dist/index.d.ts +12 -13
- package/dist/index.js +18 -19
- package/dist/v2/config/ConfigLoader.d.ts +50 -0
- package/dist/v2/config/ConfigLoader.js +205 -0
- package/dist/v2/config/DefaultConfig.d.ts +9 -0
- package/dist/v2/config/DefaultConfig.js +187 -0
- package/dist/v2/core/LearningOrchestrator.d.ts +65 -0
- package/dist/v2/core/LearningOrchestrator.js +499 -0
- package/dist/v2/core/MCPServerManager.d.ts +22 -0
- package/dist/v2/core/MCPServerManager.js +100 -0
- package/dist/v2/core/SessionManager.d.ts +72 -0
- package/dist/v2/core/SessionManager.js +200 -0
- package/dist/v2/core/YamaV2Orchestrator.d.ts +112 -0
- package/dist/v2/core/YamaV2Orchestrator.js +549 -0
- package/dist/v2/learning/FeedbackExtractor.d.ts +46 -0
- package/dist/v2/learning/FeedbackExtractor.js +237 -0
- package/dist/v2/learning/KnowledgeBaseManager.d.ts +91 -0
- package/dist/v2/learning/KnowledgeBaseManager.js +475 -0
- package/dist/v2/learning/types.d.ts +121 -0
- package/dist/v2/learning/types.js +15 -0
- package/dist/v2/prompts/EnhancementSystemPrompt.d.ts +8 -0
- package/dist/v2/prompts/EnhancementSystemPrompt.js +216 -0
- package/dist/v2/prompts/LangfusePromptManager.d.ts +48 -0
- package/dist/v2/prompts/LangfusePromptManager.js +144 -0
- package/dist/v2/prompts/LearningSystemPrompt.d.ts +11 -0
- package/dist/v2/prompts/LearningSystemPrompt.js +180 -0
- package/dist/v2/prompts/PromptBuilder.d.ts +45 -0
- package/dist/v2/prompts/PromptBuilder.js +257 -0
- package/dist/v2/prompts/ReviewSystemPrompt.d.ts +8 -0
- package/dist/v2/prompts/ReviewSystemPrompt.js +270 -0
- package/dist/v2/types/config.types.d.ts +141 -0
- package/dist/v2/types/config.types.js +5 -0
- package/dist/v2/types/mcp.types.d.ts +191 -0
- package/dist/v2/types/mcp.types.js +6 -0
- package/dist/v2/types/v2.types.d.ts +182 -0
- package/dist/v2/types/v2.types.js +42 -0
- package/dist/v2/utils/ObservabilityConfig.d.ts +22 -0
- package/dist/v2/utils/ObservabilityConfig.js +48 -0
- package/package.json +16 -10
- package/yama.config.example.yaml +259 -204
- package/dist/cli/index.d.ts +0 -12
- package/dist/cli/index.js +0 -538
- package/dist/core/ContextGatherer.d.ts +0 -110
- package/dist/core/ContextGatherer.js +0 -470
- package/dist/core/Guardian.d.ts +0 -81
- package/dist/core/Guardian.js +0 -480
- package/dist/core/providers/BitbucketProvider.d.ts +0 -105
- package/dist/core/providers/BitbucketProvider.js +0 -489
- package/dist/features/CodeReviewer.d.ts +0 -173
- package/dist/features/CodeReviewer.js +0 -1707
- package/dist/features/DescriptionEnhancer.d.ts +0 -70
- package/dist/features/DescriptionEnhancer.js +0 -511
- package/dist/features/MultiInstanceProcessor.d.ts +0 -74
- package/dist/features/MultiInstanceProcessor.js +0 -360
- package/dist/types/index.d.ts +0 -624
- package/dist/types/index.js +0 -104
- package/dist/utils/Cache.d.ts +0 -103
- package/dist/utils/Cache.js +0 -444
- package/dist/utils/ConfigManager.d.ts +0 -88
- package/dist/utils/ConfigManager.js +0 -602
- package/dist/utils/ContentSimilarityService.d.ts +0 -74
- package/dist/utils/ContentSimilarityService.js +0 -215
- package/dist/utils/ExactDuplicateRemover.d.ts +0 -77
- package/dist/utils/ExactDuplicateRemover.js +0 -361
- package/dist/utils/Logger.d.ts +0 -31
- package/dist/utils/Logger.js +0 -214
- package/dist/utils/MemoryBankManager.d.ts +0 -73
- package/dist/utils/MemoryBankManager.js +0 -310
- package/dist/utils/ParallelProcessing.d.ts +0 -140
- package/dist/utils/ParallelProcessing.js +0 -333
- package/dist/utils/ProviderLimits.d.ts +0 -58
- package/dist/utils/ProviderLimits.js +0 -143
- package/dist/utils/RetryManager.d.ts +0 -78
- package/dist/utils/RetryManager.js +0 -205
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Content Similarity Service for Semantic Deduplication
|
|
3
|
-
* Uses AI to compare violations with existing PR comments for semantic similarity
|
|
4
|
-
*/
|
|
5
|
-
import { Violation, PRComment, AIProviderConfig } from "../types/index.js";
|
|
6
|
-
export interface SimilarityResult {
|
|
7
|
-
violationIndex: number;
|
|
8
|
-
commentIndex: number;
|
|
9
|
-
violationId: string;
|
|
10
|
-
commentId: number;
|
|
11
|
-
similarityScore: number;
|
|
12
|
-
reasoning?: string;
|
|
13
|
-
}
|
|
14
|
-
export interface SimilarityBatch {
|
|
15
|
-
violations: Array<{
|
|
16
|
-
index: number;
|
|
17
|
-
id: string;
|
|
18
|
-
content: string;
|
|
19
|
-
}>;
|
|
20
|
-
comments: Array<{
|
|
21
|
-
index: number;
|
|
22
|
-
id: number;
|
|
23
|
-
content: string;
|
|
24
|
-
}>;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Service for calculating semantic similarity between violations and PR comments
|
|
28
|
-
*/
|
|
29
|
-
export declare class ContentSimilarityService {
|
|
30
|
-
private neurolink;
|
|
31
|
-
private aiConfig;
|
|
32
|
-
constructor(aiConfig: AIProviderConfig);
|
|
33
|
-
/**
|
|
34
|
-
* Calculate similarity scores between violations and comments in batches
|
|
35
|
-
*/
|
|
36
|
-
batchCalculateSimilarity(violations: Violation[], comments: PRComment[], batchSize?: number): Promise<SimilarityResult[]>;
|
|
37
|
-
/**
|
|
38
|
-
* Prepare violation content for AI analysis
|
|
39
|
-
*/
|
|
40
|
-
private prepareViolationContent;
|
|
41
|
-
/**
|
|
42
|
-
* Prepare comment content for AI analysis
|
|
43
|
-
*/
|
|
44
|
-
private prepareCommentContent;
|
|
45
|
-
/**
|
|
46
|
-
* Extract meaningful content from violation for comparison
|
|
47
|
-
*/
|
|
48
|
-
private extractViolationContent;
|
|
49
|
-
/**
|
|
50
|
-
* Extract meaningful content from comment for comparison
|
|
51
|
-
*/
|
|
52
|
-
private extractCommentContent;
|
|
53
|
-
/**
|
|
54
|
-
* Process a single batch of violations against all comments
|
|
55
|
-
*/
|
|
56
|
-
private processSimilarityBatch;
|
|
57
|
-
/**
|
|
58
|
-
* Create AI prompt for similarity analysis
|
|
59
|
-
*/
|
|
60
|
-
private createSimilarityPrompt;
|
|
61
|
-
/**
|
|
62
|
-
* Parse AI response to extract similarity results
|
|
63
|
-
*/
|
|
64
|
-
private parseSimilarityResponse;
|
|
65
|
-
/**
|
|
66
|
-
* Simple delay utility for rate limiting
|
|
67
|
-
*/
|
|
68
|
-
private delay;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Factory function to create ContentSimilarityService
|
|
72
|
-
*/
|
|
73
|
-
export declare function createContentSimilarityService(aiConfig: AIProviderConfig): ContentSimilarityService;
|
|
74
|
-
//# sourceMappingURL=ContentSimilarityService.d.ts.map
|
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Content Similarity Service for Semantic Deduplication
|
|
3
|
-
* Uses AI to compare violations with existing PR comments for semantic similarity
|
|
4
|
-
*/
|
|
5
|
-
import { logger } from "./Logger.js";
|
|
6
|
-
/**
|
|
7
|
-
* Service for calculating semantic similarity between violations and PR comments
|
|
8
|
-
*/
|
|
9
|
-
export class ContentSimilarityService {
|
|
10
|
-
neurolink;
|
|
11
|
-
aiConfig;
|
|
12
|
-
constructor(aiConfig) {
|
|
13
|
-
this.aiConfig = aiConfig;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Calculate similarity scores between violations and comments in batches
|
|
17
|
-
*/
|
|
18
|
-
async batchCalculateSimilarity(violations, comments, batchSize = 15) {
|
|
19
|
-
const startTime = Date.now();
|
|
20
|
-
logger.debug(`🔍 Starting semantic similarity analysis: ${violations.length} violations vs ${comments.length} comments`);
|
|
21
|
-
if (violations.length === 0 || comments.length === 0) {
|
|
22
|
-
logger.debug("⏭️ No violations or comments to compare, skipping similarity analysis");
|
|
23
|
-
return [];
|
|
24
|
-
}
|
|
25
|
-
// Prepare violation and comment content for AI analysis
|
|
26
|
-
const violationData = this.prepareViolationContent(violations);
|
|
27
|
-
const commentData = this.prepareCommentContent(comments);
|
|
28
|
-
logger.debug(`📝 Prepared ${violationData.length} violations and ${commentData.length} comments for analysis`);
|
|
29
|
-
// Process in batches to manage token limits
|
|
30
|
-
const allResults = [];
|
|
31
|
-
const totalBatches = Math.ceil(violations.length / batchSize);
|
|
32
|
-
for (let i = 0; i < violations.length; i += batchSize) {
|
|
33
|
-
const batchIndex = Math.floor(i / batchSize) + 1;
|
|
34
|
-
const violationBatch = violationData.slice(i, i + batchSize);
|
|
35
|
-
logger.debug(`🔄 Processing batch ${batchIndex}/${totalBatches} (${violationBatch.length} violations)`);
|
|
36
|
-
try {
|
|
37
|
-
const batchResults = await this.processSimilarityBatch(violationBatch, commentData);
|
|
38
|
-
allResults.push(...batchResults);
|
|
39
|
-
logger.debug(`✅ Batch ${batchIndex} completed: ${batchResults.length} similarity scores calculated`);
|
|
40
|
-
// Add delay between batches to avoid rate limiting
|
|
41
|
-
if (batchIndex < totalBatches) {
|
|
42
|
-
await this.delay(1000);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
catch (error) {
|
|
46
|
-
logger.error(`❌ Batch ${batchIndex} failed: ${error.message}`);
|
|
47
|
-
// Continue with next batch instead of failing entirely
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
const processingTime = Date.now() - startTime;
|
|
51
|
-
logger.success(`✅ Semantic similarity analysis completed: ${allResults.length} comparisons in ${processingTime}ms`);
|
|
52
|
-
return allResults;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Prepare violation content for AI analysis
|
|
56
|
-
*/
|
|
57
|
-
prepareViolationContent(violations) {
|
|
58
|
-
return violations.map((violation, index) => ({
|
|
59
|
-
index,
|
|
60
|
-
id: `violation_${index}`,
|
|
61
|
-
content: this.extractViolationContent(violation),
|
|
62
|
-
}));
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Prepare comment content for AI analysis
|
|
66
|
-
*/
|
|
67
|
-
prepareCommentContent(comments) {
|
|
68
|
-
return comments.map((comment, index) => ({
|
|
69
|
-
index,
|
|
70
|
-
id: comment.id,
|
|
71
|
-
content: this.extractCommentContent(comment),
|
|
72
|
-
}));
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Extract meaningful content from violation for comparison
|
|
76
|
-
*/
|
|
77
|
-
extractViolationContent(violation) {
|
|
78
|
-
const parts = [
|
|
79
|
-
`Issue: ${violation.issue}`,
|
|
80
|
-
`Message: ${violation.message}`,
|
|
81
|
-
violation.file ? `File: ${violation.file}` : "",
|
|
82
|
-
violation.code_snippet ? `Code: ${violation.code_snippet}` : "",
|
|
83
|
-
`Severity: ${violation.severity}`,
|
|
84
|
-
`Category: ${violation.category}`,
|
|
85
|
-
].filter(Boolean);
|
|
86
|
-
return parts.join(" | ");
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Extract meaningful content from comment for comparison
|
|
90
|
-
*/
|
|
91
|
-
extractCommentContent(comment) {
|
|
92
|
-
const parts = [
|
|
93
|
-
`Comment: ${comment.text}`,
|
|
94
|
-
comment.anchor?.filePath ? `File: ${comment.anchor.filePath}` : "",
|
|
95
|
-
`Author: ${comment.author.displayName || comment.author.name}`,
|
|
96
|
-
].filter(Boolean);
|
|
97
|
-
return parts.join(" | ");
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Process a single batch of violations against all comments
|
|
101
|
-
*/
|
|
102
|
-
async processSimilarityBatch(violationBatch, commentData) {
|
|
103
|
-
const prompt = this.createSimilarityPrompt(violationBatch, commentData);
|
|
104
|
-
try {
|
|
105
|
-
// Initialize NeuroLink if not already done
|
|
106
|
-
if (!this.neurolink) {
|
|
107
|
-
const { NeuroLink } = await import("@juspay/neurolink");
|
|
108
|
-
this.neurolink = new NeuroLink();
|
|
109
|
-
}
|
|
110
|
-
// Use NeuroLink for AI analysis
|
|
111
|
-
const result = await this.neurolink.generate({
|
|
112
|
-
input: { text: prompt },
|
|
113
|
-
systemPrompt: "You are an expert code reviewer analyzing semantic similarity between violations and comments. Provide accurate similarity scores based on content analysis.",
|
|
114
|
-
provider: this.aiConfig.provider || "auto",
|
|
115
|
-
model: this.aiConfig.model || "best",
|
|
116
|
-
temperature: 0.1, // Low temperature for consistent similarity scoring
|
|
117
|
-
maxTokens: this.aiConfig.maxTokens || 4000,
|
|
118
|
-
timeout: "5m",
|
|
119
|
-
enableAnalytics: this.aiConfig.enableAnalytics || false,
|
|
120
|
-
enableEvaluation: false,
|
|
121
|
-
});
|
|
122
|
-
return this.parseSimilarityResponse(result.content, violationBatch, commentData);
|
|
123
|
-
}
|
|
124
|
-
catch (error) {
|
|
125
|
-
logger.error(`Failed to process similarity batch: ${error.message}`);
|
|
126
|
-
throw error;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Create AI prompt for similarity analysis
|
|
131
|
-
*/
|
|
132
|
-
createSimilarityPrompt(violations, comments) {
|
|
133
|
-
const violationList = violations
|
|
134
|
-
.map((v, i) => `${i + 1}. ${v.content}`)
|
|
135
|
-
.join("\n");
|
|
136
|
-
const commentList = comments
|
|
137
|
-
.map((c, i) => `${i + 1}. ${c.content.substring(0, 300)}${c.content.length > 300 ? "..." : ""}`)
|
|
138
|
-
.join("\n");
|
|
139
|
-
return `
|
|
140
|
-
Analyze the semantic similarity between these code review violations and existing PR comments.
|
|
141
|
-
|
|
142
|
-
NEW VIOLATIONS TO CHECK:
|
|
143
|
-
${violationList}
|
|
144
|
-
|
|
145
|
-
EXISTING PR COMMENTS:
|
|
146
|
-
${commentList}
|
|
147
|
-
|
|
148
|
-
For each violation, determine if it's semantically similar to any existing comment. Consider:
|
|
149
|
-
- Same or similar issues being reported
|
|
150
|
-
- Same file or code area being discussed
|
|
151
|
-
- Similar concerns or suggestions
|
|
152
|
-
- Related security, performance, or code quality topics
|
|
153
|
-
|
|
154
|
-
Return a JSON array with similarity scores (0-100) for each violation-comment pair that has meaningful similarity (score >= 70).
|
|
155
|
-
|
|
156
|
-
Format: [{"violation": 1, "comment": 2, "score": 85, "reasoning": "Both discuss the same security vulnerability in authentication"}, ...]
|
|
157
|
-
|
|
158
|
-
Only include pairs with scores >= 70. If no meaningful similarities exist, return an empty array [].
|
|
159
|
-
`.trim();
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Parse AI response to extract similarity results
|
|
163
|
-
*/
|
|
164
|
-
parseSimilarityResponse(response, violationBatch, commentData) {
|
|
165
|
-
try {
|
|
166
|
-
// Extract JSON from response
|
|
167
|
-
const jsonMatch = response.match(/\[[\s\S]*\]/);
|
|
168
|
-
if (!jsonMatch) {
|
|
169
|
-
logger.debug("No JSON array found in AI response, assuming no similarities");
|
|
170
|
-
return [];
|
|
171
|
-
}
|
|
172
|
-
const similarities = JSON.parse(jsonMatch[0]);
|
|
173
|
-
const results = [];
|
|
174
|
-
for (const similarity of similarities) {
|
|
175
|
-
const violationIndex = similarity.violation - 1; // Convert from 1-based to 0-based
|
|
176
|
-
const commentIndex = similarity.comment - 1;
|
|
177
|
-
if (violationIndex >= 0 &&
|
|
178
|
-
violationIndex < violationBatch.length &&
|
|
179
|
-
commentIndex >= 0 &&
|
|
180
|
-
commentIndex < commentData.length) {
|
|
181
|
-
const violation = violationBatch[violationIndex];
|
|
182
|
-
const comment = commentData[commentIndex];
|
|
183
|
-
results.push({
|
|
184
|
-
violationIndex: violation.index,
|
|
185
|
-
commentIndex: comment.index,
|
|
186
|
-
violationId: violation.id,
|
|
187
|
-
commentId: comment.id,
|
|
188
|
-
similarityScore: similarity.score,
|
|
189
|
-
reasoning: similarity.reasoning,
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
logger.debug(`📊 Parsed ${results.length} similarity results from AI response`);
|
|
194
|
-
return results;
|
|
195
|
-
}
|
|
196
|
-
catch (error) {
|
|
197
|
-
logger.error(`Failed to parse similarity response: ${error.message}`);
|
|
198
|
-
logger.debug(`Raw response: ${response}`);
|
|
199
|
-
return [];
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Simple delay utility for rate limiting
|
|
204
|
-
*/
|
|
205
|
-
delay(ms) {
|
|
206
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Factory function to create ContentSimilarityService
|
|
211
|
-
*/
|
|
212
|
-
export function createContentSimilarityService(aiConfig) {
|
|
213
|
-
return new ContentSimilarityService(aiConfig);
|
|
214
|
-
}
|
|
215
|
-
//# sourceMappingURL=ContentSimilarityService.js.map
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Exact Duplicate Removal Utility for Multi-Instance Processing
|
|
3
|
-
* Handles deduplication of violations from multiple Neurolink SDK instances
|
|
4
|
-
*/
|
|
5
|
-
import { Violation, DeduplicationResult, InstanceResult, PRComment, CommentDeduplicationResult, AIProviderConfig } from "../types/index.js";
|
|
6
|
-
/**
|
|
7
|
-
* Exact Duplicate Remover for Multi-Instance Results
|
|
8
|
-
* Implements multi-level deduplication strategy
|
|
9
|
-
*/
|
|
10
|
-
export declare class ExactDuplicateRemover {
|
|
11
|
-
/**
|
|
12
|
-
* Remove exact duplicates from multiple instance results
|
|
13
|
-
*/
|
|
14
|
-
removeDuplicates(instanceResults: InstanceResult[]): DeduplicationResult;
|
|
15
|
-
/**
|
|
16
|
-
* Flatten violations from all instances with source tracking
|
|
17
|
-
*/
|
|
18
|
-
private flattenViolationsWithSource;
|
|
19
|
-
/**
|
|
20
|
-
* Remove exact hash duplicates (Level 1)
|
|
21
|
-
*/
|
|
22
|
-
private removeExactHashDuplicates;
|
|
23
|
-
/**
|
|
24
|
-
* Remove normalized duplicates (Level 2)
|
|
25
|
-
*/
|
|
26
|
-
private removeNormalizedDuplicates;
|
|
27
|
-
/**
|
|
28
|
-
* Remove same file+line duplicates (Level 3)
|
|
29
|
-
*/
|
|
30
|
-
private removeSameLineDuplicates;
|
|
31
|
-
/**
|
|
32
|
-
* Create hash for exact violation matching
|
|
33
|
-
*/
|
|
34
|
-
private createViolationHash;
|
|
35
|
-
/**
|
|
36
|
-
* Create hash for normalized violation matching
|
|
37
|
-
*/
|
|
38
|
-
private createNormalizedViolationHash;
|
|
39
|
-
/**
|
|
40
|
-
* Normalize code snippet for comparison
|
|
41
|
-
*/
|
|
42
|
-
private normalizeCodeSnippet;
|
|
43
|
-
/**
|
|
44
|
-
* Normalize text for comparison
|
|
45
|
-
*/
|
|
46
|
-
private normalizeText;
|
|
47
|
-
/**
|
|
48
|
-
* Resolve duplicate by severity (and potentially other factors)
|
|
49
|
-
*/
|
|
50
|
-
private resolveDuplicateBySeverity;
|
|
51
|
-
/**
|
|
52
|
-
* Track which instance contributed how many violations
|
|
53
|
-
*/
|
|
54
|
-
private trackContributions;
|
|
55
|
-
/**
|
|
56
|
-
* Remove source tracking information from violation
|
|
57
|
-
*/
|
|
58
|
-
private stripSourceInfo;
|
|
59
|
-
/**
|
|
60
|
-
* Remove violations that duplicate existing PR comments using semantic similarity
|
|
61
|
-
* Uses AI-powered ContentSimilarityService for intelligent deduplication
|
|
62
|
-
*/
|
|
63
|
-
removeAgainstExistingComments(newViolations: Violation[], existingComments: PRComment[], aiConfig: AIProviderConfig, similarityThreshold?: number): Promise<CommentDeduplicationResult>;
|
|
64
|
-
/**
|
|
65
|
-
* Get detailed deduplication statistics
|
|
66
|
-
*/
|
|
67
|
-
getDeduplicationStats(result: DeduplicationResult): string;
|
|
68
|
-
/**
|
|
69
|
-
* Get detailed comment deduplication statistics
|
|
70
|
-
*/
|
|
71
|
-
getCommentDeduplicationStats(result: CommentDeduplicationResult): string;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Factory function to create ExactDuplicateRemover
|
|
75
|
-
*/
|
|
76
|
-
export declare function createExactDuplicateRemover(): ExactDuplicateRemover;
|
|
77
|
-
//# sourceMappingURL=ExactDuplicateRemover.d.ts.map
|