@aituber-onair/manneri 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 (48) hide show
  1. package/README.ja.md +609 -0
  2. package/README.md +600 -0
  3. package/dist/analyzers/KeywordExtractor.d.ts +48 -0
  4. package/dist/analyzers/KeywordExtractor.js +253 -0
  5. package/dist/analyzers/KeywordExtractor.js.map +1 -0
  6. package/dist/analyzers/PatternDetector.d.ts +38 -0
  7. package/dist/analyzers/PatternDetector.js +244 -0
  8. package/dist/analyzers/PatternDetector.js.map +1 -0
  9. package/dist/analyzers/SimilarityAnalyzer.d.ts +23 -0
  10. package/dist/analyzers/SimilarityAnalyzer.js +153 -0
  11. package/dist/analyzers/SimilarityAnalyzer.js.map +1 -0
  12. package/dist/config/defaultPrompts.d.ts +5 -0
  13. package/dist/config/defaultPrompts.js +22 -0
  14. package/dist/config/defaultPrompts.js.map +1 -0
  15. package/dist/core/ConversationAnalyzer.d.ts +51 -0
  16. package/dist/core/ConversationAnalyzer.js +213 -0
  17. package/dist/core/ConversationAnalyzer.js.map +1 -0
  18. package/dist/core/ManneriDetector.d.ts +64 -0
  19. package/dist/core/ManneriDetector.js +251 -0
  20. package/dist/core/ManneriDetector.js.map +1 -0
  21. package/dist/generators/PromptGenerator.d.ts +15 -0
  22. package/dist/generators/PromptGenerator.js +45 -0
  23. package/dist/generators/PromptGenerator.js.map +1 -0
  24. package/dist/index.d.ts +21 -0
  25. package/dist/index.js +27 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/persistence/LocalStoragePersistenceProvider.d.ts +45 -0
  28. package/dist/persistence/LocalStoragePersistenceProvider.js +102 -0
  29. package/dist/persistence/LocalStoragePersistenceProvider.js.map +1 -0
  30. package/dist/persistence/index.d.ts +5 -0
  31. package/dist/persistence/index.js +5 -0
  32. package/dist/persistence/index.js.map +1 -0
  33. package/dist/types/index.d.ts +114 -0
  34. package/dist/types/index.js +28 -0
  35. package/dist/types/index.js.map +1 -0
  36. package/dist/types/persistence.d.ts +78 -0
  37. package/dist/types/persistence.js +2 -0
  38. package/dist/types/persistence.js.map +1 -0
  39. package/dist/types/prompts.d.ts +22 -0
  40. package/dist/types/prompts.js +36 -0
  41. package/dist/types/prompts.js.map +1 -0
  42. package/dist/utils/browserUtils.d.ts +20 -0
  43. package/dist/utils/browserUtils.js +206 -0
  44. package/dist/utils/browserUtils.js.map +1 -0
  45. package/dist/utils/textUtils.d.ts +10 -0
  46. package/dist/utils/textUtils.js +269 -0
  47. package/dist/utils/textUtils.js.map +1 -0
  48. package/package.json +50 -0
@@ -0,0 +1,253 @@
1
+ import { tokenize, extractKeywords } from '../utils/textUtils.js';
2
+ import { measurePerformance } from '../utils/browserUtils.js';
3
+ export class KeywordExtractor {
4
+ constructor(options = {}) {
5
+ this.keywordFrequencies = new Map();
6
+ this.topicClusters = new Map();
7
+ this.maxKeywords = 50;
8
+ this.maxContextLength = 100;
9
+ this.options = {
10
+ minWordLength: 2,
11
+ maxNgrams: 3,
12
+ includeStopWords: false,
13
+ caseSensitive: false,
14
+ language: 'auto',
15
+ ...options,
16
+ };
17
+ }
18
+ extractKeywordsFromMessage(message) {
19
+ return measurePerformance('extractKeywords', () => extractKeywords(message.content, this.options), false);
20
+ }
21
+ extractKeywordsFromMessages(messages) {
22
+ const allKeywords = [];
23
+ for (const message of messages) {
24
+ const keywords = this.extractKeywordsFromMessage(message);
25
+ allKeywords.push(...keywords);
26
+ }
27
+ const keywordCounts = new Map();
28
+ for (const keyword of allKeywords) {
29
+ keywordCounts.set(keyword, (keywordCounts.get(keyword) || 0) + 1);
30
+ }
31
+ return Array.from(keywordCounts.entries())
32
+ .sort((a, b) => b[1] - a[1])
33
+ .slice(0, 20)
34
+ .map(([keyword]) => keyword);
35
+ }
36
+ analyzeKeywordFrequencies(messages) {
37
+ const keywordData = new Map();
38
+ for (const message of messages) {
39
+ const keywords = this.extractKeywordsFromMessage(message);
40
+ const timestamp = message.timestamp || Date.now();
41
+ for (const keyword of keywords) {
42
+ if (keywordData.has(keyword)) {
43
+ const data = keywordData.get(keyword);
44
+ if (!data)
45
+ continue;
46
+ data.frequency++;
47
+ data.lastSeen = Math.max(data.lastSeen, timestamp);
48
+ data.score = this.calculateKeywordScore(data.frequency, data.firstSeen, data.lastSeen);
49
+ if (data.contexts.length < 5) {
50
+ const context = message.content.substring(0, this.maxContextLength);
51
+ if (!data.contexts.includes(context)) {
52
+ data.contexts.push(context);
53
+ }
54
+ }
55
+ }
56
+ else {
57
+ keywordData.set(keyword, {
58
+ keyword,
59
+ frequency: 1,
60
+ score: 1,
61
+ firstSeen: timestamp,
62
+ lastSeen: timestamp,
63
+ contexts: [message.content.substring(0, this.maxContextLength)],
64
+ });
65
+ }
66
+ }
67
+ }
68
+ return Array.from(keywordData.values())
69
+ .sort((a, b) => b.score - a.score)
70
+ .slice(0, this.maxKeywords);
71
+ }
72
+ detectTopicShift(recentMessages, historicalMessages, threshold = 0.5) {
73
+ const recentKeywords = new Set(this.extractKeywordsFromMessages(recentMessages));
74
+ const historicalKeywords = new Set(this.extractKeywordsFromMessages(historicalMessages));
75
+ const intersection = new Set([...recentKeywords].filter((x) => historicalKeywords.has(x)));
76
+ const union = new Set([...recentKeywords, ...historicalKeywords]);
77
+ const similarity = intersection.size / union.size;
78
+ const hasShift = similarity < threshold;
79
+ const newTopics = Array.from(recentKeywords).filter((k) => !historicalKeywords.has(k));
80
+ const oldTopics = Array.from(historicalKeywords).filter((k) => !recentKeywords.has(k));
81
+ return {
82
+ hasShift,
83
+ newTopics,
84
+ oldTopics,
85
+ };
86
+ }
87
+ analyzeTopicClusters(messages) {
88
+ const keywordFrequencies = this.analyzeKeywordFrequencies(messages);
89
+ const clusters = new Map();
90
+ for (const message of messages) {
91
+ const keywords = this.extractKeywordsFromMessage(message);
92
+ const timestamp = message.timestamp || Date.now();
93
+ for (const keyword of keywords) {
94
+ const relatedKeywords = this.findRelatedKeywords(keyword, keywordFrequencies);
95
+ const clusterId = this.generateClusterId(relatedKeywords);
96
+ if (clusters.has(clusterId)) {
97
+ const cluster = clusters.get(clusterId);
98
+ if (!cluster)
99
+ continue;
100
+ cluster.messageCount++;
101
+ cluster.lastMessage = Math.max(cluster.lastMessage, timestamp);
102
+ cluster.score = this.calculateClusterScore(cluster);
103
+ }
104
+ else {
105
+ clusters.set(clusterId, {
106
+ id: clusterId,
107
+ keywords: relatedKeywords,
108
+ score: 1,
109
+ messageCount: 1,
110
+ firstMessage: timestamp,
111
+ lastMessage: timestamp,
112
+ });
113
+ }
114
+ }
115
+ }
116
+ return Array.from(clusters.values())
117
+ .sort((a, b) => b.score - a.score)
118
+ .slice(0, 10);
119
+ }
120
+ getTopicInfo(messages) {
121
+ const clusters = this.analyzeTopicClusters(messages);
122
+ return clusters.map((cluster) => ({
123
+ keywords: cluster.keywords,
124
+ score: cluster.score,
125
+ category: this.categorizeKeywords(cluster.keywords),
126
+ confidence: Math.min(cluster.score / 10, 1.0),
127
+ }));
128
+ }
129
+ findRepeatedKeywords(messages, minRepetitions = 3, windowSize = 5) {
130
+ const keywordPositions = new Map();
131
+ for (let i = 0; i < messages.length; i++) {
132
+ const keywords = this.extractKeywordsFromMessage(messages[i]);
133
+ for (const keyword of keywords) {
134
+ if (!keywordPositions.has(keyword)) {
135
+ keywordPositions.set(keyword, []);
136
+ }
137
+ keywordPositions.get(keyword)?.push(i);
138
+ }
139
+ }
140
+ const repeatedKeywords = [];
141
+ for (const [keyword, positions] of keywordPositions) {
142
+ if (positions.length >= minRepetitions) {
143
+ const density = this.calculateKeywordDensity(positions, windowSize);
144
+ if (density > 0.5) {
145
+ repeatedKeywords.push({
146
+ keyword,
147
+ positions,
148
+ density,
149
+ });
150
+ }
151
+ }
152
+ }
153
+ return repeatedKeywords.sort((a, b) => b.density - a.density);
154
+ }
155
+ calculateKeywordScore(frequency, firstSeen, lastSeen) {
156
+ const recencyFactor = 1 - (Date.now() - lastSeen) / (24 * 60 * 60 * 1000);
157
+ const persistenceFactor = (lastSeen - firstSeen) / (60 * 60 * 1000);
158
+ return (frequency *
159
+ (1 + Math.max(0, recencyFactor)) *
160
+ (1 + Math.min(1, persistenceFactor / 24)));
161
+ }
162
+ findRelatedKeywords(keyword, frequencies) {
163
+ const related = [keyword];
164
+ for (const freq of frequencies) {
165
+ if (freq.keyword !== keyword && freq.frequency > 1) {
166
+ const similarity = this.calculateSemanticSimilarity(keyword, freq.keyword);
167
+ if (similarity > 0.3) {
168
+ related.push(freq.keyword);
169
+ }
170
+ }
171
+ }
172
+ return related.slice(0, 5);
173
+ }
174
+ calculateSemanticSimilarity(word1, word2) {
175
+ const tokens1 = tokenize(word1, this.options);
176
+ const tokens2 = tokenize(word2, this.options);
177
+ if (tokens1.length === 0 || tokens2.length === 0)
178
+ return 0;
179
+ const set1 = new Set(tokens1);
180
+ const set2 = new Set(tokens2);
181
+ const intersection = new Set([...set1].filter((x) => set2.has(x)));
182
+ const union = new Set([...set1, ...set2]);
183
+ return intersection.size / union.size;
184
+ }
185
+ generateClusterId(keywords) {
186
+ return keywords.sort().join('|');
187
+ }
188
+ calculateClusterScore(cluster) {
189
+ const keywordCount = cluster.keywords.length;
190
+ const messageCount = cluster.messageCount;
191
+ const timeSpan = cluster.lastMessage - cluster.firstMessage;
192
+ return (keywordCount *
193
+ messageCount *
194
+ (1 + Math.min(1, timeSpan / (60 * 60 * 1000))));
195
+ }
196
+ categorizeKeywords(keywords) {
197
+ const categories = {
198
+ 技術: [
199
+ '技術',
200
+ 'プログラミング',
201
+ 'コード',
202
+ 'システム',
203
+ 'API',
204
+ 'データベース',
205
+ 'サーバー',
206
+ ],
207
+ エンターテイメント: [
208
+ 'ゲーム',
209
+ '音楽',
210
+ '映画',
211
+ 'アニメ',
212
+ 'TV',
213
+ 'スポーツ',
214
+ ],
215
+ 日常: ['食事', '天気', '仕事', '家族', '友達', '学校'],
216
+ その他: [],
217
+ };
218
+ for (const [category, categoryKeywords] of Object.entries(categories)) {
219
+ if (category === 'その他')
220
+ continue;
221
+ const matchCount = keywords.filter((k) => categoryKeywords.some((ck) => k.includes(ck) || ck.includes(k))).length;
222
+ if (matchCount > 0) {
223
+ return category;
224
+ }
225
+ }
226
+ return 'その他';
227
+ }
228
+ calculateKeywordDensity(positions, windowSize) {
229
+ if (positions.length < 2)
230
+ return 0;
231
+ let maxDensity = 0;
232
+ for (let i = 0; i < positions.length - 1; i++) {
233
+ let count = 1;
234
+ const start = positions[i];
235
+ for (let j = i + 1; j < positions.length; j++) {
236
+ if (positions[j] - start < windowSize) {
237
+ count++;
238
+ }
239
+ else {
240
+ break;
241
+ }
242
+ }
243
+ const density = count / windowSize;
244
+ maxDensity = Math.max(maxDensity, density);
245
+ }
246
+ return maxDensity;
247
+ }
248
+ clearCache() {
249
+ this.keywordFrequencies.clear();
250
+ this.topicClusters.clear();
251
+ }
252
+ }
253
+ //# sourceMappingURL=KeywordExtractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KeywordExtractor.js","sourceRoot":"","sources":["../../src/analyzers/KeywordExtractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { Message, ConversationPattern } from '../types/index.js';
2
+ export interface PatternDetectionResult {
3
+ patterns: ConversationPattern[];
4
+ severity: 'low' | 'medium' | 'high';
5
+ confidence: number;
6
+ }
7
+ export interface MessageSequence {
8
+ messages: Message[];
9
+ pattern: string;
10
+ frequency: number;
11
+ positions: number[];
12
+ }
13
+ export declare class PatternDetector {
14
+ private readonly detectedPatterns;
15
+ private readonly sequenceCache;
16
+ private readonly maxPatterns;
17
+ private readonly minPatternLength;
18
+ private readonly maxPatternLength;
19
+ detectPatterns(messages: Message[]): PatternDetectionResult;
20
+ private findNewPatterns;
21
+ private extractSequencePatterns;
22
+ private findRepeatedPatterns;
23
+ private findStructuralPatterns;
24
+ private extractRoleSequences;
25
+ private findRepeatedRoleSequences;
26
+ private createPatternSignature;
27
+ private deduplicatePatterns;
28
+ private calculateSeverity;
29
+ private calculateConfidence;
30
+ getPatternStatistics(): {
31
+ totalPatterns: number;
32
+ averageFrequency: number;
33
+ mostFrequentPattern: ConversationPattern | null;
34
+ oldestPattern: ConversationPattern | null;
35
+ };
36
+ private cleanupOldPatterns;
37
+ clearPatterns(): void;
38
+ }
@@ -0,0 +1,244 @@
1
+ import { generateId } from '../utils/browserUtils.js';
2
+ import { calculateTextSimilarity } from '../utils/textUtils.js';
3
+ export class PatternDetector {
4
+ constructor() {
5
+ this.detectedPatterns = new Map();
6
+ this.sequenceCache = new Map();
7
+ this.maxPatterns = 100;
8
+ this.minPatternLength = 2;
9
+ this.maxPatternLength = 5;
10
+ }
11
+ detectPatterns(messages) {
12
+ this.cleanupOldPatterns();
13
+ const newPatterns = this.findNewPatterns(messages);
14
+ const repeatedPatterns = this.findRepeatedPatterns(messages);
15
+ const structuralPatterns = this.findStructuralPatterns(messages);
16
+ const allPatterns = [
17
+ ...newPatterns,
18
+ ...repeatedPatterns,
19
+ ...structuralPatterns,
20
+ ];
21
+ const uniquePatterns = this.deduplicatePatterns(allPatterns);
22
+ // Clean up again to maintain the limit
23
+ this.cleanupOldPatterns();
24
+ const severity = this.calculateSeverity(uniquePatterns);
25
+ const confidence = this.calculateConfidence(uniquePatterns, messages.length);
26
+ return {
27
+ patterns: uniquePatterns,
28
+ severity,
29
+ confidence,
30
+ };
31
+ }
32
+ findNewPatterns(messages) {
33
+ const newPatterns = [];
34
+ for (let length = this.minPatternLength; length <= this.maxPatternLength; length++) {
35
+ const patterns = this.extractSequencePatterns(messages, length);
36
+ newPatterns.push(...patterns);
37
+ }
38
+ return newPatterns;
39
+ }
40
+ extractSequencePatterns(messages, sequenceLength) {
41
+ const patterns = [];
42
+ const sequenceMap = new Map();
43
+ for (let i = 0; i <= messages.length - sequenceLength; i++) {
44
+ const sequence = messages.slice(i, i + sequenceLength);
45
+ const pattern = this.createPatternSignature(sequence);
46
+ if (sequenceMap.has(pattern)) {
47
+ const existing = sequenceMap.get(pattern);
48
+ if (!existing)
49
+ continue;
50
+ existing.frequency++;
51
+ existing.positions.push(i);
52
+ }
53
+ else {
54
+ sequenceMap.set(pattern, {
55
+ messages: sequence,
56
+ pattern,
57
+ frequency: 1,
58
+ positions: [i],
59
+ });
60
+ }
61
+ }
62
+ for (const [patternSignature, sequence] of sequenceMap) {
63
+ if (sequence.frequency >= 2) {
64
+ const pattern = {
65
+ id: generateId(),
66
+ pattern: patternSignature,
67
+ frequency: sequence.frequency,
68
+ firstSeen: sequence.messages[0].timestamp || Date.now(),
69
+ lastSeen: sequence.messages[sequence.messages.length - 1].timestamp ||
70
+ Date.now(),
71
+ messages: sequence.messages,
72
+ };
73
+ patterns.push(pattern);
74
+ this.detectedPatterns.set(pattern.id, pattern);
75
+ }
76
+ }
77
+ return patterns;
78
+ }
79
+ findRepeatedPatterns(messages) {
80
+ const repeatedPatterns = [];
81
+ const foundPairs = new Set();
82
+ for (let i = 0; i < messages.length - 1; i++) {
83
+ const currentMessage = messages[i];
84
+ for (let j = i + 1; j < messages.length; j++) {
85
+ const compareMessage = messages[j];
86
+ if (currentMessage.role === compareMessage.role) {
87
+ const similarity = calculateTextSimilarity(currentMessage.content, compareMessage.content);
88
+ if (similarity >= 0.8) {
89
+ // Create a unique key for this pair to avoid duplicates
90
+ const pairKey = `${Math.min(i, j)}_${Math.max(i, j)}`;
91
+ if (!foundPairs.has(pairKey)) {
92
+ foundPairs.add(pairKey);
93
+ const pattern = {
94
+ id: generateId(),
95
+ pattern: `Repeated ${currentMessage.role} message`,
96
+ frequency: 2,
97
+ firstSeen: currentMessage.timestamp || Date.now(),
98
+ lastSeen: compareMessage.timestamp || Date.now(),
99
+ messages: [currentMessage, compareMessage],
100
+ };
101
+ repeatedPatterns.push(pattern);
102
+ this.detectedPatterns.set(pattern.id, pattern);
103
+ }
104
+ }
105
+ }
106
+ }
107
+ }
108
+ return repeatedPatterns;
109
+ }
110
+ findStructuralPatterns(messages) {
111
+ const structuralPatterns = [];
112
+ const roleSequences = this.extractRoleSequences(messages);
113
+ const repeatedRoleSequences = this.findRepeatedRoleSequences(roleSequences);
114
+ for (const sequence of repeatedRoleSequences) {
115
+ const pattern = {
116
+ id: generateId(),
117
+ pattern: `Role sequence: ${sequence.pattern}`,
118
+ frequency: sequence.frequency,
119
+ firstSeen: Date.now(),
120
+ lastSeen: Date.now(),
121
+ messages: sequence.messages,
122
+ };
123
+ structuralPatterns.push(pattern);
124
+ }
125
+ return structuralPatterns;
126
+ }
127
+ extractRoleSequences(messages) {
128
+ const sequences = [];
129
+ for (let length = 2; length <= Math.min(4, messages.length); length++) {
130
+ for (let i = 0; i <= messages.length - length; i++) {
131
+ const sequence = messages.slice(i, i + length);
132
+ const pattern = sequence.map((m) => m.role).join('-');
133
+ sequences.push({
134
+ messages: sequence,
135
+ pattern,
136
+ frequency: 1,
137
+ positions: [i],
138
+ });
139
+ }
140
+ }
141
+ return sequences;
142
+ }
143
+ findRepeatedRoleSequences(sequences) {
144
+ const sequenceMap = new Map();
145
+ for (const sequence of sequences) {
146
+ if (sequenceMap.has(sequence.pattern)) {
147
+ const existing = sequenceMap.get(sequence.pattern);
148
+ if (!existing)
149
+ continue;
150
+ existing.frequency++;
151
+ existing.positions.push(...sequence.positions);
152
+ }
153
+ else {
154
+ sequenceMap.set(sequence.pattern, { ...sequence });
155
+ }
156
+ }
157
+ return Array.from(sequenceMap.values()).filter((seq) => seq.frequency >= 3);
158
+ }
159
+ createPatternSignature(messages) {
160
+ return messages
161
+ .map((m) => {
162
+ const contentWords = m.content.split(/\s+/).slice(0, 3);
163
+ return `${m.role}:${contentWords.join(' ')}`;
164
+ })
165
+ .join('|');
166
+ }
167
+ deduplicatePatterns(patterns) {
168
+ const unique = new Map();
169
+ for (const pattern of patterns) {
170
+ const key = `${pattern.pattern}_${pattern.frequency}`;
171
+ const existingPattern = unique.get(key);
172
+ if (!unique.has(key) ||
173
+ (existingPattern && existingPattern.frequency < pattern.frequency)) {
174
+ unique.set(key, pattern);
175
+ }
176
+ }
177
+ return Array.from(unique.values()).sort((a, b) => b.frequency - a.frequency);
178
+ }
179
+ calculateSeverity(patterns) {
180
+ if (patterns.length === 0)
181
+ return 'low';
182
+ const maxFrequency = Math.max(...patterns.map((p) => p.frequency));
183
+ const totalPatterns = patterns.length;
184
+ if (maxFrequency >= 5 || totalPatterns >= 10)
185
+ return 'high';
186
+ if (maxFrequency >= 3 || totalPatterns >= 5)
187
+ return 'medium';
188
+ return 'low';
189
+ }
190
+ calculateConfidence(patterns, totalMessages) {
191
+ if (patterns.length === 0 || totalMessages === 0)
192
+ return 0;
193
+ const totalPatternMessages = patterns.reduce((sum, p) => sum + p.messages.length * p.frequency, 0);
194
+ const confidence = Math.min(totalPatternMessages / totalMessages, 1.0);
195
+ return Math.round(confidence * 100) / 100;
196
+ }
197
+ getPatternStatistics() {
198
+ const patterns = Array.from(this.detectedPatterns.values());
199
+ if (patterns.length === 0) {
200
+ return {
201
+ totalPatterns: 0,
202
+ averageFrequency: 0,
203
+ mostFrequentPattern: null,
204
+ oldestPattern: null,
205
+ };
206
+ }
207
+ const totalFrequency = patterns.reduce((sum, p) => sum + p.frequency, 0);
208
+ const averageFrequency = totalFrequency / patterns.length;
209
+ const mostFrequentPattern = patterns.reduce((max, p) => p.frequency > max.frequency ? p : max);
210
+ const oldestPattern = patterns.reduce((oldest, p) => p.firstSeen < oldest.firstSeen ? p : oldest);
211
+ return {
212
+ totalPatterns: patterns.length,
213
+ averageFrequency: Math.round(averageFrequency * 100) / 100,
214
+ mostFrequentPattern,
215
+ oldestPattern,
216
+ };
217
+ }
218
+ cleanupOldPatterns() {
219
+ const now = Date.now();
220
+ const maxAge = 24 * 60 * 60 * 1000; // 24時間
221
+ // First, remove old patterns
222
+ for (const [id, pattern] of this.detectedPatterns) {
223
+ if (now - pattern.lastSeen > maxAge) {
224
+ this.detectedPatterns.delete(id);
225
+ }
226
+ }
227
+ // Then, enforce the maximum pattern limit
228
+ while (this.detectedPatterns.size >= this.maxPatterns) {
229
+ const sortedPatterns = Array.from(this.detectedPatterns.values()).sort((a, b) => a.lastSeen - b.lastSeen);
230
+ if (sortedPatterns.length > 0) {
231
+ // Remove the oldest pattern
232
+ this.detectedPatterns.delete(sortedPatterns[0].id);
233
+ }
234
+ else {
235
+ break;
236
+ }
237
+ }
238
+ }
239
+ clearPatterns() {
240
+ this.detectedPatterns.clear();
241
+ this.sequenceCache.clear();
242
+ }
243
+ }
244
+ //# sourceMappingURL=PatternDetector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PatternDetector.js","sourceRoot":"","sources":["../../src/analyzers/PatternDetector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { Message, SimilarityResult, TextAnalysisOptions } from '../types/index.js';
2
+ export declare class SimilarityAnalyzer {
3
+ private readonly options;
4
+ private readonly cache;
5
+ private readonly cacheTimeout;
6
+ constructor(options?: Partial<TextAnalysisOptions>);
7
+ calculateSimilarity(text1: string, text2: string): number;
8
+ analyzeSimilarity(currentMessage: Message, previousMessages: Message[], threshold?: number): SimilarityResult;
9
+ findSimilarMessages(targetMessage: Message, messages: Message[], threshold?: number, sameRoleOnly?: boolean): Message[];
10
+ analyzeSequenceSimilarity(messages: Message[], sequenceLength?: number, threshold?: number): Array<{
11
+ sequence: Message[];
12
+ similarity: number;
13
+ }>;
14
+ private calculateSequenceSimilarity;
15
+ analyzeNgramSimilarity(text1: string, text2: string, ngramSize?: number): number;
16
+ private getCacheKey;
17
+ private setCacheValue;
18
+ clearCache(): void;
19
+ getCacheStats(): {
20
+ size: number;
21
+ hitRate: number;
22
+ };
23
+ }