@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,153 @@
1
+ import { calculateTextSimilarity, tokenize, generateNgrams, } from '../utils/textUtils.js';
2
+ import { measurePerformance } from '../utils/browserUtils.js';
3
+ export class SimilarityAnalyzer {
4
+ constructor(options = {}) {
5
+ this.cache = new Map();
6
+ this.cacheTimeout = 300000; // 5 minutes
7
+ this.options = {
8
+ minWordLength: 2,
9
+ maxNgrams: 3,
10
+ includeStopWords: false,
11
+ caseSensitive: false,
12
+ language: 'auto',
13
+ ...options,
14
+ };
15
+ }
16
+ calculateSimilarity(text1, text2) {
17
+ const cacheKey = this.getCacheKey(text1, text2);
18
+ const cached = this.cache.get(cacheKey);
19
+ if (cached !== undefined) {
20
+ return cached;
21
+ }
22
+ const similarity = measurePerformance('calculateSimilarity', () => calculateTextSimilarity(text1, text2, this.options), false);
23
+ this.setCacheValue(cacheKey, similarity);
24
+ return similarity;
25
+ }
26
+ analyzeSimilarity(currentMessage, previousMessages, threshold = 0.7) {
27
+ if (previousMessages.length === 0) {
28
+ return {
29
+ score: 0,
30
+ isRepeated: false,
31
+ matchedMessages: [],
32
+ };
33
+ }
34
+ const currentContent = currentMessage.content.trim();
35
+ if (currentContent.length === 0) {
36
+ return {
37
+ score: 0,
38
+ isRepeated: false,
39
+ matchedMessages: [],
40
+ };
41
+ }
42
+ let maxSimilarity = 0;
43
+ const matchedMessages = [];
44
+ for (const message of previousMessages) {
45
+ if (message.role === currentMessage.role) {
46
+ const similarity = this.calculateSimilarity(currentContent, message.content);
47
+ if (similarity > maxSimilarity) {
48
+ maxSimilarity = similarity;
49
+ }
50
+ if (similarity >= threshold) {
51
+ matchedMessages.push(message);
52
+ }
53
+ }
54
+ }
55
+ return {
56
+ score: maxSimilarity,
57
+ isRepeated: maxSimilarity >= threshold,
58
+ matchedMessages,
59
+ };
60
+ }
61
+ findSimilarMessages(targetMessage, messages, threshold = 0.7, sameRoleOnly = true) {
62
+ const similarMessages = [];
63
+ const targetContent = targetMessage.content.trim();
64
+ for (const message of messages) {
65
+ if (message === targetMessage)
66
+ continue;
67
+ if (sameRoleOnly && message.role !== targetMessage.role)
68
+ continue;
69
+ const similarity = this.calculateSimilarity(targetContent, message.content);
70
+ if (similarity >= threshold) {
71
+ similarMessages.push(message);
72
+ }
73
+ }
74
+ return similarMessages;
75
+ }
76
+ analyzeSequenceSimilarity(messages, sequenceLength = 3, threshold = 0.7) {
77
+ if (messages.length < sequenceLength * 2) {
78
+ return [];
79
+ }
80
+ const sequences = [];
81
+ for (let i = 0; i <= messages.length - sequenceLength; i++) {
82
+ const sequence1 = messages.slice(i, i + sequenceLength);
83
+ for (let j = i + sequenceLength; j <= messages.length - sequenceLength; j++) {
84
+ const sequence2 = messages.slice(j, j + sequenceLength);
85
+ const similarity = this.calculateSequenceSimilarity(sequence1, sequence2);
86
+ if (similarity >= threshold) {
87
+ sequences.push({
88
+ sequence: sequence1,
89
+ similarity,
90
+ });
91
+ }
92
+ }
93
+ }
94
+ return sequences.sort((a, b) => b.similarity - a.similarity);
95
+ }
96
+ calculateSequenceSimilarity(sequence1, sequence2) {
97
+ if (sequence1.length !== sequence2.length)
98
+ return 0;
99
+ let totalSimilarity = 0;
100
+ let validPairs = 0;
101
+ for (let i = 0; i < sequence1.length; i++) {
102
+ if (sequence1[i].role === sequence2[i].role) {
103
+ const similarity = this.calculateSimilarity(sequence1[i].content, sequence2[i].content);
104
+ totalSimilarity += similarity;
105
+ validPairs++;
106
+ }
107
+ }
108
+ return validPairs > 0 ? totalSimilarity / validPairs : 0;
109
+ }
110
+ analyzeNgramSimilarity(text1, text2, ngramSize = 2) {
111
+ const tokens1 = tokenize(text1, this.options);
112
+ const tokens2 = tokenize(text2, this.options);
113
+ if (tokens1.length === 0 && tokens2.length === 0)
114
+ return 1.0;
115
+ if (tokens1.length === 0 || tokens2.length === 0)
116
+ return 0.0;
117
+ const ngrams1 = new Set(generateNgrams(tokens1, ngramSize));
118
+ const ngrams2 = new Set(generateNgrams(tokens2, ngramSize));
119
+ if (ngrams1.size === 0 && ngrams2.size === 0)
120
+ return 1.0;
121
+ if (ngrams1.size === 0 || ngrams2.size === 0)
122
+ return 0.0;
123
+ const intersection = new Set([...ngrams1].filter((x) => ngrams2.has(x)));
124
+ const union = new Set([...ngrams1, ...ngrams2]);
125
+ return intersection.size / union.size;
126
+ }
127
+ getCacheKey(text1, text2) {
128
+ const sortedTexts = [text1, text2].sort();
129
+ return `${sortedTexts[0]}||${sortedTexts[1]}`;
130
+ }
131
+ setCacheValue(key, value) {
132
+ this.cache.set(key, value);
133
+ setTimeout(() => {
134
+ this.cache.delete(key);
135
+ }, this.cacheTimeout);
136
+ if (this.cache.size > 1000) {
137
+ const keysToDelete = Array.from(this.cache.keys()).slice(0, 100);
138
+ for (const k of keysToDelete) {
139
+ this.cache.delete(k);
140
+ }
141
+ }
142
+ }
143
+ clearCache() {
144
+ this.cache.clear();
145
+ }
146
+ getCacheStats() {
147
+ return {
148
+ size: this.cache.size,
149
+ hitRate: 0,
150
+ };
151
+ }
152
+ }
153
+ //# sourceMappingURL=SimilarityAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SimilarityAnalyzer.js","sourceRoot":"","sources":["../../src/analyzers/SimilarityAnalyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { LocalizedPrompts } from '../types/prompts.js';
2
+ /**
3
+ * Default prompts for multiple languages
4
+ */
5
+ export declare const DEFAULT_PROMPTS: LocalizedPrompts;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Default prompts for multiple languages
3
+ */
4
+ export const DEFAULT_PROMPTS = {
5
+ ja: {
6
+ intervention: [
7
+ '話題を変えて、新しい内容について話してください。',
8
+ '別の角度から話題を展開してみましょう。',
9
+ '新しいテーマで会話を続けてください。',
10
+ '会話に変化をもたらすため、違う話題にしてみませんか?',
11
+ ],
12
+ },
13
+ en: {
14
+ intervention: [
15
+ 'Please change the topic and talk about something new.',
16
+ "Let's explore the topic from a different angle.",
17
+ 'Please continue the conversation with a new theme.',
18
+ 'How about changing to a different topic to bring variety to the conversation?',
19
+ ],
20
+ },
21
+ };
22
+ //# sourceMappingURL=defaultPrompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaultPrompts.js","sourceRoot":"","sources":["../../src/config/defaultPrompts.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAqB;IAC/C,EAAE,EAAE;QACF,YAAY,EAAE;YACZ,0BAA0B;YAC1B,qBAAqB;YACrB,oBAAoB;YACpB,4BAA4B;SAC7B;KACF;IACD,EAAE,EAAE;QACF,YAAY,EAAE;YACZ,uDAAuD;YACvD,iDAAiD;YACjD,oDAAoD;YACpD,+EAA+E;SAChF;KACF;CACF,CAAC"}
@@ -0,0 +1,51 @@
1
+ import type { Message, AnalysisResult, TextAnalysisOptions } from '../types/index.js';
2
+ export interface ConversationAnalyzerOptions {
3
+ similarityThreshold: number;
4
+ patternThreshold: number;
5
+ keywordThreshold: number;
6
+ analysisWindow: number;
7
+ enableSimilarityAnalysis: boolean;
8
+ enablePatternDetection: boolean;
9
+ enableKeywordAnalysis: boolean;
10
+ enableTopicTracking: boolean;
11
+ textAnalysisOptions: Partial<TextAnalysisOptions>;
12
+ }
13
+ export declare class ConversationAnalyzer {
14
+ private readonly similarityAnalyzer;
15
+ private readonly keywordExtractor;
16
+ private readonly patternDetector;
17
+ private readonly options;
18
+ constructor(options?: Partial<ConversationAnalyzerOptions>);
19
+ analyzeConversation(messages: Message[]): AnalysisResult;
20
+ private getAnalysisWindow;
21
+ private analyzeSimilarity;
22
+ private analyzeTopics;
23
+ private analyzePatterns;
24
+ private shouldIntervene;
25
+ private getInterventionReason;
26
+ private createEmptySimilarityResult;
27
+ analyzeMessageFlow(messages: Message[]): {
28
+ avgMessageLength: number;
29
+ roleDistribution: Record<string, number>;
30
+ conversationRhythm: number[];
31
+ engagementScore: number;
32
+ };
33
+ private calculateConversationRhythm;
34
+ private calculateEngagementScore;
35
+ detectConversationLoops(messages: Message[]): {
36
+ hasLoop: boolean;
37
+ loopLength: number;
38
+ loopStart: number;
39
+ confidence: number;
40
+ };
41
+ private calculateSequenceSimilarity;
42
+ getAnalysisStats(): {
43
+ totalAnalyses: number;
44
+ averageAnalysisTime: number;
45
+ cacheHitRate: number;
46
+ memoryUsage: number;
47
+ };
48
+ clearCache(): void;
49
+ updateOptions(options: Partial<ConversationAnalyzerOptions>): void;
50
+ getOptions(): ConversationAnalyzerOptions;
51
+ }
@@ -0,0 +1,213 @@
1
+ import { SimilarityAnalyzer } from '../analyzers/SimilarityAnalyzer.js';
2
+ import { KeywordExtractor } from '../analyzers/KeywordExtractor.js';
3
+ import { PatternDetector } from '../analyzers/PatternDetector.js';
4
+ import { measurePerformance } from '../utils/browserUtils.js';
5
+ export class ConversationAnalyzer {
6
+ constructor(options = {}) {
7
+ this.options = {
8
+ similarityThreshold: 0.75,
9
+ patternThreshold: 0.8,
10
+ keywordThreshold: 0.7,
11
+ analysisWindow: 10,
12
+ enableSimilarityAnalysis: true,
13
+ enablePatternDetection: true,
14
+ enableKeywordAnalysis: true,
15
+ enableTopicTracking: true,
16
+ textAnalysisOptions: {},
17
+ ...options,
18
+ };
19
+ this.similarityAnalyzer = new SimilarityAnalyzer(this.options.textAnalysisOptions);
20
+ this.keywordExtractor = new KeywordExtractor(this.options.textAnalysisOptions);
21
+ this.patternDetector = new PatternDetector();
22
+ }
23
+ analyzeConversation(messages) {
24
+ return measurePerformance('analyzeConversation', () => {
25
+ const analysisWindow = this.getAnalysisWindow(messages);
26
+ const similarity = this.options.enableSimilarityAnalysis
27
+ ? this.analyzeSimilarity(analysisWindow)
28
+ : this.createEmptySimilarityResult();
29
+ const topics = this.options.enableTopicTracking
30
+ ? this.analyzeTopics(analysisWindow)
31
+ : [];
32
+ const patterns = this.options.enablePatternDetection
33
+ ? this.analyzePatterns(analysisWindow)
34
+ : [];
35
+ const shouldIntervene = this.shouldIntervene(similarity, topics, patterns);
36
+ const interventionReason = this.getInterventionReason(similarity, topics, patterns);
37
+ return {
38
+ similarity,
39
+ topics,
40
+ patterns,
41
+ shouldIntervene,
42
+ interventionReason,
43
+ lastIntervention: 0,
44
+ };
45
+ });
46
+ }
47
+ getAnalysisWindow(messages) {
48
+ const windowSize = Math.min(this.options.analysisWindow, messages.length);
49
+ return messages.slice(-windowSize);
50
+ }
51
+ analyzeSimilarity(messages) {
52
+ if (messages.length < 2) {
53
+ return this.createEmptySimilarityResult();
54
+ }
55
+ const latestMessage = messages[messages.length - 1];
56
+ const previousMessages = messages.slice(0, -1);
57
+ return this.similarityAnalyzer.analyzeSimilarity(latestMessage, previousMessages, this.options.similarityThreshold);
58
+ }
59
+ analyzeTopics(messages) {
60
+ if (!this.options.enableTopicTracking || messages.length === 0) {
61
+ return [];
62
+ }
63
+ return this.keywordExtractor.getTopicInfo(messages);
64
+ }
65
+ analyzePatterns(messages) {
66
+ if (!this.options.enablePatternDetection || messages.length < 3) {
67
+ return [];
68
+ }
69
+ const result = this.patternDetector.detectPatterns(messages);
70
+ return result.patterns;
71
+ }
72
+ shouldIntervene(similarity, topics, patterns) {
73
+ const similarityTrigger = similarity.isRepeated &&
74
+ similarity.score >= this.options.similarityThreshold;
75
+ const patternTrigger = patterns.some((p) => p.frequency >= 3);
76
+ const topicTrigger = topics.length > 0 && topics.some((t) => t.confidence > 0.8);
77
+ return similarityTrigger || patternTrigger || topicTrigger;
78
+ }
79
+ getInterventionReason(similarity, topics, patterns) {
80
+ const reasons = [];
81
+ if (similarity.isRepeated) {
82
+ reasons.push(`類似度が高い (${Math.round(similarity.score * 100)}%)`);
83
+ }
84
+ if (patterns.length > 0) {
85
+ const maxFrequency = Math.max(...patterns.map((p) => p.frequency));
86
+ reasons.push(`パターンの繰り返し (最大${maxFrequency}回)`);
87
+ }
88
+ if (topics.length > 0) {
89
+ const highConfidenceTopics = topics.filter((t) => t.confidence > 0.8);
90
+ if (highConfidenceTopics.length > 0) {
91
+ reasons.push(`話題の偏り (${highConfidenceTopics.length}件)`);
92
+ }
93
+ }
94
+ return reasons.length > 0 ? reasons.join(', ') : '閾値を超過';
95
+ }
96
+ createEmptySimilarityResult() {
97
+ return {
98
+ score: 0,
99
+ isRepeated: false,
100
+ matchedMessages: [],
101
+ };
102
+ }
103
+ analyzeMessageFlow(messages) {
104
+ if (messages.length === 0) {
105
+ return {
106
+ avgMessageLength: 0,
107
+ roleDistribution: {},
108
+ conversationRhythm: [],
109
+ engagementScore: 0,
110
+ };
111
+ }
112
+ const avgMessageLength = messages.reduce((sum, m) => sum + m.content.length, 0) / messages.length;
113
+ const roleDistribution = {};
114
+ for (const m of messages) {
115
+ roleDistribution[m.role] = (roleDistribution[m.role] || 0) + 1;
116
+ }
117
+ const conversationRhythm = this.calculateConversationRhythm(messages);
118
+ const engagementScore = this.calculateEngagementScore(messages);
119
+ return {
120
+ avgMessageLength: Math.round(avgMessageLength),
121
+ roleDistribution,
122
+ conversationRhythm,
123
+ engagementScore,
124
+ };
125
+ }
126
+ calculateConversationRhythm(messages) {
127
+ const rhythm = [];
128
+ for (let i = 1; i < messages.length; i++) {
129
+ const prevTime = messages[i - 1].timestamp || 0;
130
+ const currTime = messages[i].timestamp || 0;
131
+ if (prevTime > 0 && currTime > 0) {
132
+ const interval = currTime - prevTime;
133
+ rhythm.push(interval);
134
+ }
135
+ }
136
+ return rhythm;
137
+ }
138
+ calculateEngagementScore(messages) {
139
+ if (messages.length === 0)
140
+ return 0;
141
+ const avgLength = messages.reduce((sum, m) => sum + m.content.length, 0) / messages.length;
142
+ const uniqueWords = new Set();
143
+ for (const m of messages) {
144
+ const words = m.content.split(/\s+/);
145
+ for (const word of words) {
146
+ uniqueWords.add(word.toLowerCase());
147
+ }
148
+ }
149
+ const vocabularyDiversity = uniqueWords.size / messages.length;
150
+ const lengthScore = Math.min(avgLength / 100, 1.0);
151
+ return Math.round((vocabularyDiversity + lengthScore) * 50);
152
+ }
153
+ detectConversationLoops(messages) {
154
+ const result = {
155
+ hasLoop: false,
156
+ loopLength: 0,
157
+ loopStart: -1,
158
+ confidence: 0,
159
+ };
160
+ if (messages.length < 4)
161
+ return result;
162
+ for (let loopLength = 2; loopLength <= Math.floor(messages.length / 2); loopLength++) {
163
+ for (let start = 0; start <= messages.length - loopLength * 2; start++) {
164
+ const sequence1 = messages.slice(start, start + loopLength);
165
+ const sequence2 = messages.slice(start + loopLength, start + loopLength * 2);
166
+ const similarity = this.calculateSequenceSimilarity(sequence1, sequence2);
167
+ if (similarity > 0.8) {
168
+ result.hasLoop = true;
169
+ result.loopLength = loopLength;
170
+ result.loopStart = start;
171
+ result.confidence = similarity;
172
+ return result;
173
+ }
174
+ }
175
+ }
176
+ return result;
177
+ }
178
+ calculateSequenceSimilarity(seq1, seq2) {
179
+ if (seq1.length !== seq2.length)
180
+ return 0;
181
+ let totalSimilarity = 0;
182
+ let validComparisons = 0;
183
+ for (let i = 0; i < seq1.length; i++) {
184
+ if (seq1[i].role === seq2[i].role) {
185
+ const similarity = this.similarityAnalyzer.calculateSimilarity(seq1[i].content, seq2[i].content);
186
+ totalSimilarity += similarity;
187
+ validComparisons++;
188
+ }
189
+ }
190
+ return validComparisons > 0 ? totalSimilarity / validComparisons : 0;
191
+ }
192
+ getAnalysisStats() {
193
+ const similarityStats = this.similarityAnalyzer.getCacheStats();
194
+ return {
195
+ totalAnalyses: 0,
196
+ averageAnalysisTime: 0,
197
+ cacheHitRate: similarityStats.hitRate,
198
+ memoryUsage: similarityStats.size,
199
+ };
200
+ }
201
+ clearCache() {
202
+ this.similarityAnalyzer.clearCache();
203
+ this.keywordExtractor.clearCache();
204
+ this.patternDetector.clearPatterns();
205
+ }
206
+ updateOptions(options) {
207
+ Object.assign(this.options, options);
208
+ }
209
+ getOptions() {
210
+ return { ...this.options };
211
+ }
212
+ }
213
+ //# sourceMappingURL=ConversationAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConversationAnalyzer.js","sourceRoot":"","sources":["../../src/core/ConversationAnalyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { Message, ManneriConfig, AnalysisResult, DiversificationPrompt, ManneriEvent, ManneriEventHandler, StorageData, PersistenceProvider } from '../types/index.js';
2
+ import { ConversationAnalyzer } from './ConversationAnalyzer.js';
3
+ export declare class ManneriDetector {
4
+ private readonly config;
5
+ private readonly analyzer;
6
+ private promptGenerator;
7
+ private patternDetector;
8
+ private readonly persistenceProvider?;
9
+ private readonly eventEmitter;
10
+ private interventionHistory;
11
+ private lastAnalysisResult;
12
+ constructor(config?: Partial<ManneriConfig>, options?: {
13
+ persistenceProvider?: PersistenceProvider;
14
+ });
15
+ detectManneri(messages: Message[]): boolean;
16
+ shouldIntervene(messages: Message[]): boolean;
17
+ generateDiversificationPrompt(messages: Message[]): DiversificationPrompt;
18
+ generateAiDiversificationPrompt(messages: Message[]): Promise<DiversificationPrompt>;
19
+ analyzeConversation(messages: Message[]): AnalysisResult;
20
+ updateConfig(newConfig: Partial<ManneriConfig>): void;
21
+ getConfig(): ManneriConfig;
22
+ on<K extends keyof ManneriEvent>(event: K, handler: ManneriEventHandler<ManneriEvent[K]>): void;
23
+ off<K extends keyof ManneriEvent>(event: K, handler: ManneriEventHandler<ManneriEvent[K]>): void;
24
+ getStatistics(): {
25
+ totalInterventions: number;
26
+ averageInterventionInterval: number;
27
+ lastIntervention: number | null;
28
+ configuredThresholds: {
29
+ similarity: number;
30
+ repetition: number;
31
+ cooldown: number;
32
+ };
33
+ analysisStats: ReturnType<ConversationAnalyzer['getAnalysisStats']>;
34
+ };
35
+ clearHistory(): void;
36
+ exportData(): StorageData;
37
+ importData(data: StorageData): void;
38
+ private createAnalyzerOptions;
39
+ private recordIntervention;
40
+ private emit;
41
+ /**
42
+ * Manually save data using the persistence provider
43
+ */
44
+ save(): Promise<boolean>;
45
+ /**
46
+ * Manually load data using the persistence provider
47
+ */
48
+ load(): Promise<boolean>;
49
+ /**
50
+ * Manually cleanup old data
51
+ */
52
+ cleanup(maxAge?: number): Promise<number>;
53
+ /**
54
+ * Check if persistence provider is configured
55
+ */
56
+ hasPersistenceProvider(): boolean;
57
+ /**
58
+ * Get persistence provider info (if available)
59
+ */
60
+ getPersistenceInfo(): {
61
+ provider: string;
62
+ available: boolean;
63
+ } | null;
64
+ }