/** * @fileoverview Trigger phrase overlap detection for skills * @module @skillsmith/core/matching/OverlapDetector * @see SMI-604: Trigger phrase overlap detection * * Detects similarity between skill trigger phrases to prevent * recommending skills that overlap too much with installed ones. * * @example * const detector = new OverlapDetector({ useFallback: true }); * const overlap = await detector.detectOverlap(skill1, skill2); * if (overlap.overlapScore > 0.8) { * console.log('Skills are too similar:', overlap.overlappingPhrases); * } */ import { type EmbeddingServiceOptions } from '../embeddings/index.js'; /** * Skill with trigger phrases for overlap detection */ export interface TriggerPhraseSkill { /** Unique skill identifier */ id: string; /** Skill display name */ name: string; /** Trigger phrases that activate this skill */ triggerPhrases: string[]; } /** * Result of overlap detection between two skills */ export interface OverlapResult { /** First skill ID */ skillId1: string; /** Second skill ID */ skillId2: string; /** Overall overlap score (0-1) */ overlapScore: number; /** Specific phrases that overlap */ overlappingPhrases: Array<{ phrase1: string; phrase2: string; similarity: number; }>; /** Whether skills are considered duplicates */ isDuplicate: boolean; } /** * Result of filtering skills by overlap */ export interface FilteredSkillsResult { /** Skills that passed the overlap filter */ accepted: TriggerPhraseSkill[]; /** Skills that were rejected due to overlap */ rejected: Array<{ skill: TriggerPhraseSkill; overlapsWith: string; overlapScore: number; }>; } /** * Options for OverlapDetector */ export interface OverlapDetectorOptions extends EmbeddingServiceOptions { /** Similarity threshold for phrase matching (0-1, default 0.75) */ phraseThreshold?: number; /** Overall overlap threshold for skill rejection (0-1, default 0.6) */ overlapThreshold?: number; /** Whether to use exact string matching in addition to semantic (default true) */ useExactMatch?: boolean; } /** * Detects overlap between skill trigger phrases. * * Uses semantic similarity to identify skills that respond to * similar user inputs, preventing confusing recommendations. * * @example * const detector = new OverlapDetector({ overlapThreshold: 0.7 }); * const result = await detector.filterByOverlap(candidates, installed); * // Use result.accepted for recommendations */ export declare class OverlapDetector { private embeddingService; private phraseEmbeddings; private readonly phraseThreshold; private readonly overlapThreshold; private readonly useExactMatch; constructor(options?: OverlapDetectorOptions); /** * Check if detector is using fallback mode */ isUsingFallback(): boolean; /** * Detect overlap between two skills. * * @param skill1 - First skill * @param skill2 - Second skill * @returns Detailed overlap analysis */ detectOverlap(skill1: TriggerPhraseSkill, skill2: TriggerPhraseSkill): Promise; /** * Check for exact string match (case-insensitive, normalized) */ private isExactMatch; /** * Get or compute embedding for a phrase */ private getPhraseEmbedding; /** * Filter candidate skills by overlap with installed skills. * * Removes candidates that have too much trigger phrase overlap * with already installed skills. * * @param candidates - Skills to consider for recommendation * @param installed - Currently installed skills * @returns Filtered results with accepted and rejected skills * * @example * const result = await detector.filterByOverlap(candidates, installed); * console.log(`Accepted: ${result.accepted.length}`); * console.log(`Rejected: ${result.rejected.length}`); */ filterByOverlap(candidates: TriggerPhraseSkill[], installed: TriggerPhraseSkill[]): Promise; /** * Find all overlapping skill pairs in a set. * * Useful for auditing a skill library for potential conflicts. * * @param skills - Skills to check for overlaps * @returns List of overlapping pairs */ findAllOverlaps(skills: TriggerPhraseSkill[]): Promise; /** * Get overlap threshold */ getOverlapThreshold(): number; /** * Get phrase similarity threshold */ getPhraseThreshold(): number; /** * Clear cached embeddings */ clear(): void; /** * Close resources */ close(): void; } export default OverlapDetector; //# sourceMappingURL=OverlapDetector.d.ts.map