@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.
- package/README.ja.md +609 -0
- package/README.md +600 -0
- package/dist/analyzers/KeywordExtractor.d.ts +48 -0
- package/dist/analyzers/KeywordExtractor.js +253 -0
- package/dist/analyzers/KeywordExtractor.js.map +1 -0
- package/dist/analyzers/PatternDetector.d.ts +38 -0
- package/dist/analyzers/PatternDetector.js +244 -0
- package/dist/analyzers/PatternDetector.js.map +1 -0
- package/dist/analyzers/SimilarityAnalyzer.d.ts +23 -0
- package/dist/analyzers/SimilarityAnalyzer.js +153 -0
- package/dist/analyzers/SimilarityAnalyzer.js.map +1 -0
- package/dist/config/defaultPrompts.d.ts +5 -0
- package/dist/config/defaultPrompts.js +22 -0
- package/dist/config/defaultPrompts.js.map +1 -0
- package/dist/core/ConversationAnalyzer.d.ts +51 -0
- package/dist/core/ConversationAnalyzer.js +213 -0
- package/dist/core/ConversationAnalyzer.js.map +1 -0
- package/dist/core/ManneriDetector.d.ts +64 -0
- package/dist/core/ManneriDetector.js +251 -0
- package/dist/core/ManneriDetector.js.map +1 -0
- package/dist/generators/PromptGenerator.d.ts +15 -0
- package/dist/generators/PromptGenerator.js +45 -0
- package/dist/generators/PromptGenerator.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/persistence/LocalStoragePersistenceProvider.d.ts +45 -0
- package/dist/persistence/LocalStoragePersistenceProvider.js +102 -0
- package/dist/persistence/LocalStoragePersistenceProvider.js.map +1 -0
- package/dist/persistence/index.d.ts +5 -0
- package/dist/persistence/index.js +5 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/types/index.d.ts +114 -0
- package/dist/types/index.js +28 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/persistence.d.ts +78 -0
- package/dist/types/persistence.js +2 -0
- package/dist/types/persistence.js.map +1 -0
- package/dist/types/prompts.d.ts +22 -0
- package/dist/types/prompts.js +36 -0
- package/dist/types/prompts.js.map +1 -0
- package/dist/utils/browserUtils.d.ts +20 -0
- package/dist/utils/browserUtils.js +206 -0
- package/dist/utils/browserUtils.js.map +1 -0
- package/dist/utils/textUtils.d.ts +10 -0
- package/dist/utils/textUtils.js +269 -0
- package/dist/utils/textUtils.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { DEFAULT_MANNERI_CONFIG } from '../types/index.js';
|
|
2
|
+
import { ConversationAnalyzer, } from './ConversationAnalyzer.js';
|
|
3
|
+
import { PromptGenerator, } from '../generators/PromptGenerator.js';
|
|
4
|
+
import { PatternDetector } from '../analyzers/PatternDetector.js';
|
|
5
|
+
import { createEventEmitter } from '../utils/browserUtils.js';
|
|
6
|
+
export class ManneriDetector {
|
|
7
|
+
constructor(config = {}, options = {}) {
|
|
8
|
+
this.eventEmitter = createEventEmitter();
|
|
9
|
+
this.interventionHistory = [];
|
|
10
|
+
this.lastAnalysisResult = null;
|
|
11
|
+
this.config = { ...DEFAULT_MANNERI_CONFIG, ...config };
|
|
12
|
+
this.persistenceProvider = options.persistenceProvider;
|
|
13
|
+
const language = this.config.language || 'ja';
|
|
14
|
+
const customPrompts = this.config.customPrompts;
|
|
15
|
+
this.analyzer = new ConversationAnalyzer(this.createAnalyzerOptions());
|
|
16
|
+
this.promptGenerator = new PromptGenerator(language, customPrompts);
|
|
17
|
+
this.patternDetector = new PatternDetector();
|
|
18
|
+
}
|
|
19
|
+
detectManneri(messages) {
|
|
20
|
+
if (messages.length < 2)
|
|
21
|
+
return false;
|
|
22
|
+
const result = this.analyzer.analyzeConversation(messages);
|
|
23
|
+
this.lastAnalysisResult = result;
|
|
24
|
+
this.emit('similarity_calculated', {
|
|
25
|
+
score: result.similarity.score,
|
|
26
|
+
threshold: this.config.similarityThreshold,
|
|
27
|
+
});
|
|
28
|
+
if (result.shouldIntervene) {
|
|
29
|
+
this.emit('pattern_detected', result);
|
|
30
|
+
}
|
|
31
|
+
return result.shouldIntervene;
|
|
32
|
+
}
|
|
33
|
+
shouldIntervene(messages) {
|
|
34
|
+
if (!this.detectManneri(messages))
|
|
35
|
+
return false;
|
|
36
|
+
const now = Date.now();
|
|
37
|
+
const lastIntervention = this.interventionHistory[this.interventionHistory.length - 1] || 0;
|
|
38
|
+
const timeSinceLastIntervention = now - lastIntervention;
|
|
39
|
+
const shouldInterveneByTime = timeSinceLastIntervention >= this.config.interventionCooldown;
|
|
40
|
+
if (!shouldInterveneByTime && this.config.debugMode) {
|
|
41
|
+
console.log(`[Manneri] Intervention skipped due to cooldown. Time remaining: ${this.config.interventionCooldown - timeSinceLastIntervention}ms`);
|
|
42
|
+
}
|
|
43
|
+
return shouldInterveneByTime;
|
|
44
|
+
}
|
|
45
|
+
generateDiversificationPrompt(messages) {
|
|
46
|
+
const options = {
|
|
47
|
+
language: this.config.language,
|
|
48
|
+
};
|
|
49
|
+
const prompt = this.promptGenerator.generateDiversificationPrompt(messages, options);
|
|
50
|
+
this.recordIntervention();
|
|
51
|
+
this.emit('intervention_triggered', prompt);
|
|
52
|
+
return prompt;
|
|
53
|
+
}
|
|
54
|
+
async generateAiDiversificationPrompt(messages) {
|
|
55
|
+
return this.generateDiversificationPrompt(messages);
|
|
56
|
+
}
|
|
57
|
+
analyzeConversation(messages) {
|
|
58
|
+
const result = this.analyzer.analyzeConversation(messages);
|
|
59
|
+
this.lastAnalysisResult = result;
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
updateConfig(newConfig) {
|
|
63
|
+
Object.assign(this.config, newConfig);
|
|
64
|
+
// Update language and prompts if changed
|
|
65
|
+
if (newConfig.language || newConfig.customPrompts) {
|
|
66
|
+
const language = this.config.language || 'ja';
|
|
67
|
+
const customPrompts = this.config.customPrompts;
|
|
68
|
+
// Update prompt generator and pattern detector
|
|
69
|
+
this.promptGenerator = new PromptGenerator(language, customPrompts);
|
|
70
|
+
this.patternDetector = new PatternDetector();
|
|
71
|
+
}
|
|
72
|
+
this.analyzer.updateOptions(this.createAnalyzerOptions());
|
|
73
|
+
this.emit('config_updated', newConfig);
|
|
74
|
+
}
|
|
75
|
+
getConfig() {
|
|
76
|
+
return { ...this.config };
|
|
77
|
+
}
|
|
78
|
+
on(event, handler) {
|
|
79
|
+
this.eventEmitter.on(event, handler);
|
|
80
|
+
}
|
|
81
|
+
off(event, handler) {
|
|
82
|
+
this.eventEmitter.off(event, handler);
|
|
83
|
+
}
|
|
84
|
+
getStatistics() {
|
|
85
|
+
const totalInterventions = this.interventionHistory.length;
|
|
86
|
+
let averageInterval = 0;
|
|
87
|
+
if (totalInterventions > 1) {
|
|
88
|
+
const intervals = [];
|
|
89
|
+
for (let i = 1; i < this.interventionHistory.length; i++) {
|
|
90
|
+
intervals.push(this.interventionHistory[i] - this.interventionHistory[i - 1]);
|
|
91
|
+
}
|
|
92
|
+
averageInterval =
|
|
93
|
+
intervals.reduce((sum, interval) => sum + interval, 0) /
|
|
94
|
+
intervals.length;
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
totalInterventions,
|
|
98
|
+
averageInterventionInterval: Math.round(averageInterval),
|
|
99
|
+
lastIntervention: this.interventionHistory[this.interventionHistory.length - 1] || null,
|
|
100
|
+
configuredThresholds: {
|
|
101
|
+
similarity: this.config.similarityThreshold,
|
|
102
|
+
repetition: this.config.repetitionLimit,
|
|
103
|
+
cooldown: this.config.interventionCooldown,
|
|
104
|
+
},
|
|
105
|
+
analysisStats: this.analyzer.getAnalysisStats(),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
clearHistory() {
|
|
109
|
+
this.interventionHistory = [];
|
|
110
|
+
this.lastAnalysisResult = null;
|
|
111
|
+
this.analyzer.clearCache();
|
|
112
|
+
this.promptGenerator.clearHistory();
|
|
113
|
+
}
|
|
114
|
+
exportData() {
|
|
115
|
+
return {
|
|
116
|
+
patterns: this.lastAnalysisResult?.patterns || [],
|
|
117
|
+
interventions: this.interventionHistory,
|
|
118
|
+
settings: this.config,
|
|
119
|
+
lastCleanup: Date.now(),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
importData(data) {
|
|
123
|
+
if (data.interventions) {
|
|
124
|
+
this.interventionHistory = data.interventions;
|
|
125
|
+
}
|
|
126
|
+
if (data.settings) {
|
|
127
|
+
this.updateConfig(data.settings);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
createAnalyzerOptions() {
|
|
131
|
+
return {
|
|
132
|
+
similarityThreshold: this.config.similarityThreshold,
|
|
133
|
+
patternThreshold: 0.8,
|
|
134
|
+
keywordThreshold: 0.7,
|
|
135
|
+
analysisWindow: this.config.lookbackWindow,
|
|
136
|
+
enableSimilarityAnalysis: true,
|
|
137
|
+
enablePatternDetection: true,
|
|
138
|
+
enableKeywordAnalysis: this.config.enableKeywordAnalysis,
|
|
139
|
+
enableTopicTracking: this.config.enableTopicTracking,
|
|
140
|
+
textAnalysisOptions: {
|
|
141
|
+
minWordLength: 2,
|
|
142
|
+
includeStopWords: false,
|
|
143
|
+
language: 'auto',
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
recordIntervention() {
|
|
148
|
+
const now = Date.now();
|
|
149
|
+
this.interventionHistory.push(now);
|
|
150
|
+
const maxHistory = 100;
|
|
151
|
+
if (this.interventionHistory.length > maxHistory) {
|
|
152
|
+
this.interventionHistory = this.interventionHistory.slice(-maxHistory);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
emit(event, data) {
|
|
156
|
+
if (this.config.debugMode) {
|
|
157
|
+
console.log(`[Manneri] Event: ${event}`, data);
|
|
158
|
+
}
|
|
159
|
+
this.eventEmitter.emit(event, data);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Manually save data using the persistence provider
|
|
163
|
+
*/
|
|
164
|
+
async save() {
|
|
165
|
+
if (!this.persistenceProvider) {
|
|
166
|
+
console.warn('ManneriDetector: No persistence provider configured');
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
const data = this.exportData();
|
|
171
|
+
const result = await this.persistenceProvider.save(data);
|
|
172
|
+
if (result) {
|
|
173
|
+
this.emit('save_success', { timestamp: Date.now() });
|
|
174
|
+
}
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
this.emit('save_error', { error: error });
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Manually load data using the persistence provider
|
|
184
|
+
*/
|
|
185
|
+
async load() {
|
|
186
|
+
if (!this.persistenceProvider) {
|
|
187
|
+
console.warn('ManneriDetector: No persistence provider configured');
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
try {
|
|
191
|
+
const data = await this.persistenceProvider.load();
|
|
192
|
+
if (data) {
|
|
193
|
+
this.importData(data);
|
|
194
|
+
this.emit('load_success', { data, timestamp: Date.now() });
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
this.emit('load_error', { error: error });
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Manually cleanup old data
|
|
206
|
+
*/
|
|
207
|
+
async cleanup(maxAge = 7 * 24 * 60 * 60 * 1000) {
|
|
208
|
+
const cutoff = Date.now() - maxAge;
|
|
209
|
+
const originalLength = this.interventionHistory.length;
|
|
210
|
+
this.interventionHistory = this.interventionHistory.filter((timestamp) => timestamp > cutoff);
|
|
211
|
+
const removed = originalLength - this.interventionHistory.length;
|
|
212
|
+
try {
|
|
213
|
+
let providerRemoved = 0;
|
|
214
|
+
if (this.persistenceProvider?.cleanup) {
|
|
215
|
+
providerRemoved = await this.persistenceProvider.cleanup(maxAge);
|
|
216
|
+
}
|
|
217
|
+
const totalRemoved = removed + providerRemoved;
|
|
218
|
+
if (totalRemoved > 0) {
|
|
219
|
+
this.emit('cleanup_completed', {
|
|
220
|
+
removedItems: totalRemoved,
|
|
221
|
+
timestamp: Date.now(),
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
return totalRemoved;
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
this.emit('cleanup_error', { error: error });
|
|
228
|
+
return removed; // Return at least the memory cleanup count
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Check if persistence provider is configured
|
|
233
|
+
*/
|
|
234
|
+
hasPersistenceProvider() {
|
|
235
|
+
return this.persistenceProvider !== undefined;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Get persistence provider info (if available)
|
|
239
|
+
*/
|
|
240
|
+
getPersistenceInfo() {
|
|
241
|
+
if (!this.persistenceProvider) {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
// Try to get info from LocalStoragePersistenceProvider
|
|
245
|
+
if ('getStorageInfo' in this.persistenceProvider) {
|
|
246
|
+
return this.persistenceProvider.getStorageInfo();
|
|
247
|
+
}
|
|
248
|
+
return { provider: 'custom', available: true };
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=ManneriDetector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ManneriDetector.js","sourceRoot":"","sources":["../../src/core/ManneriDetector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Message, DiversificationPrompt, LocalizedPrompts } from '../types/index.js';
|
|
2
|
+
export interface PromptGenerationOptions {
|
|
3
|
+
language?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare class PromptGenerator {
|
|
6
|
+
private readonly usedPrompts;
|
|
7
|
+
private readonly maxPromptHistory;
|
|
8
|
+
private language;
|
|
9
|
+
private prompts;
|
|
10
|
+
constructor(language?: string, customPrompts?: Partial<LocalizedPrompts>);
|
|
11
|
+
generateDiversificationPrompt(messages: Message[], options?: PromptGenerationOptions): DiversificationPrompt;
|
|
12
|
+
private getInterventionPrompt;
|
|
13
|
+
private selectUnusedTemplate;
|
|
14
|
+
clearHistory(): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { DEFAULT_PROMPTS } from '../config/defaultPrompts.js';
|
|
2
|
+
import { overridePrompts } from '../types/prompts.js';
|
|
3
|
+
export class PromptGenerator {
|
|
4
|
+
constructor(language = 'ja', customPrompts) {
|
|
5
|
+
this.usedPrompts = new Set();
|
|
6
|
+
this.maxPromptHistory = 50;
|
|
7
|
+
this.language = language;
|
|
8
|
+
this.prompts = overridePrompts(DEFAULT_PROMPTS, customPrompts);
|
|
9
|
+
}
|
|
10
|
+
generateDiversificationPrompt(messages, options = {}) {
|
|
11
|
+
const language = options.language || this.language;
|
|
12
|
+
const content = this.getInterventionPrompt(language);
|
|
13
|
+
return {
|
|
14
|
+
content,
|
|
15
|
+
type: 'topic_change',
|
|
16
|
+
priority: 'medium',
|
|
17
|
+
context: `Conversation length: ${messages.length} messages`,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
getInterventionPrompt(language) {
|
|
21
|
+
const langPrompts = this.prompts[language] || this.prompts.en;
|
|
22
|
+
if (!langPrompts?.intervention || langPrompts.intervention.length === 0) {
|
|
23
|
+
return 'Please change the topic and talk about something new.';
|
|
24
|
+
}
|
|
25
|
+
return this.selectUnusedTemplate(langPrompts.intervention);
|
|
26
|
+
}
|
|
27
|
+
selectUnusedTemplate(templates) {
|
|
28
|
+
const availableTemplates = templates.filter((t) => !this.usedPrompts.has(t));
|
|
29
|
+
if (availableTemplates.length === 0) {
|
|
30
|
+
this.usedPrompts.clear();
|
|
31
|
+
return templates[Math.floor(Math.random() * templates.length)];
|
|
32
|
+
}
|
|
33
|
+
const selected = availableTemplates[Math.floor(Math.random() * availableTemplates.length)];
|
|
34
|
+
this.usedPrompts.add(selected);
|
|
35
|
+
if (this.usedPrompts.size > this.maxPromptHistory) {
|
|
36
|
+
const oldestPrompt = Array.from(this.usedPrompts)[0];
|
|
37
|
+
this.usedPrompts.delete(oldestPrompt);
|
|
38
|
+
}
|
|
39
|
+
return selected;
|
|
40
|
+
}
|
|
41
|
+
clearHistory() {
|
|
42
|
+
this.usedPrompts.clear();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=PromptGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PromptGenerator.js","sourceRoot":"","sources":["../../src/generators/PromptGenerator.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAMtD,MAAM,OAAO,eAAe;IAM1B,YAAY,QAAQ,GAAG,IAAI,EAAE,aAAyC;QALrD,gBAAW,GAAgB,IAAI,GAAG,EAAE,CAAC;QACrC,qBAAgB,GAAW,EAAE,CAAC;QAK7C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,eAAe,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;IACjE,CAAC;IAED,6BAA6B,CAC3B,QAAmB,EACnB,UAAmC,EAAE;QAErC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;QACnD,MAAM,OAAO,GAAG,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QAErD,OAAO;YACL,OAAO;YACP,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,QAAQ;YAClB,OAAO,EAAE,wBAAwB,QAAQ,CAAC,MAAM,WAAW;SAC5D,CAAC;IACJ,CAAC;IAEO,qBAAqB,CAAC,QAAgB;QAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9D,IAAI,CAAC,WAAW,EAAE,YAAY,IAAI,WAAW,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxE,OAAO,uDAAuD,CAAC;QACjE,CAAC;QAED,OAAO,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;IAC7D,CAAC;IAEO,oBAAoB,CAAC,SAA4B;QACvD,MAAM,kBAAkB,GAAG,SAAS,CAAC,MAAM,CACzC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAChC,CAAC;QAEF,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;YACzB,OAAO,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QACjE,CAAC;QAED,MAAM,QAAQ,GACZ,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5E,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE/B,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAClD,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YACrD,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACxC,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,YAAY;QACV,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export { ManneriDetector } from './core/ManneriDetector.js';
|
|
2
|
+
export { ConversationAnalyzer } from './core/ConversationAnalyzer.js';
|
|
3
|
+
export { SimilarityAnalyzer } from './analyzers/SimilarityAnalyzer.js';
|
|
4
|
+
export { KeywordExtractor } from './analyzers/KeywordExtractor.js';
|
|
5
|
+
export { PatternDetector } from './analyzers/PatternDetector.js';
|
|
6
|
+
export { PromptGenerator } from './generators/PromptGenerator.js';
|
|
7
|
+
export type { Message, ManneriConfig, SimilarityResult, ConversationPattern, TopicInfo, AnalysisResult, DiversificationPrompt, TextAnalysisOptions, StorageData, ManneriEvent, ManneriEventHandler, } from './types/index.js';
|
|
8
|
+
export { DEFAULT_MANNERI_CONFIG, getPromptTemplate, overridePrompts, } from './types/index.js';
|
|
9
|
+
export { DEFAULT_PROMPTS } from './config/defaultPrompts.js';
|
|
10
|
+
export { LocalStoragePersistenceProvider } from './persistence/LocalStoragePersistenceProvider.js';
|
|
11
|
+
export type { PersistenceProvider, PersistenceConfig, PersistenceEvents, } from './types/persistence.js';
|
|
12
|
+
export { calculateTextSimilarity, extractKeywords, normalizeText, tokenize, generateNgrams, calculateJaccardSimilarity, calculateCosineSimilarity, } from './utils/textUtils.js';
|
|
13
|
+
export { isBrowserEnvironment, saveToLocalStorage, loadFromLocalStorage, clearLocalStorage, cleanupOldData, debounce, throttle, measurePerformance, asyncMeasurePerformance, createEventEmitter, generateId, isValidConfig, } from './utils/browserUtils.js';
|
|
14
|
+
export declare const VERSION = "0.1.0";
|
|
15
|
+
export declare function createManneriDetector(config?: Partial<import('./types/index.js').ManneriConfig>): ManneriDetector;
|
|
16
|
+
import { ConversationAnalyzer } from './core/ConversationAnalyzer.js';
|
|
17
|
+
export declare function createConversationAnalyzer(options?: Partial<import('./core/ConversationAnalyzer.js').ConversationAnalyzerOptions>): ConversationAnalyzer;
|
|
18
|
+
import { PromptGenerator } from './generators/PromptGenerator.js';
|
|
19
|
+
export declare function createPromptGenerator(language?: string, customPrompts?: Partial<import('./types/prompts.js').LocalizedPrompts>): PromptGenerator;
|
|
20
|
+
import { ManneriDetector } from './core/ManneriDetector.js';
|
|
21
|
+
export default ManneriDetector;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export { ManneriDetector } from './core/ManneriDetector.js';
|
|
2
|
+
export { ConversationAnalyzer } from './core/ConversationAnalyzer.js';
|
|
3
|
+
export { SimilarityAnalyzer } from './analyzers/SimilarityAnalyzer.js';
|
|
4
|
+
export { KeywordExtractor } from './analyzers/KeywordExtractor.js';
|
|
5
|
+
export { PatternDetector } from './analyzers/PatternDetector.js';
|
|
6
|
+
export { PromptGenerator } from './generators/PromptGenerator.js';
|
|
7
|
+
export { DEFAULT_MANNERI_CONFIG, getPromptTemplate, overridePrompts, } from './types/index.js';
|
|
8
|
+
export { DEFAULT_PROMPTS } from './config/defaultPrompts.js';
|
|
9
|
+
// Export persistence providers
|
|
10
|
+
export { LocalStoragePersistenceProvider } from './persistence/LocalStoragePersistenceProvider.js';
|
|
11
|
+
export { calculateTextSimilarity, extractKeywords, normalizeText, tokenize, generateNgrams, calculateJaccardSimilarity, calculateCosineSimilarity, } from './utils/textUtils.js';
|
|
12
|
+
export { isBrowserEnvironment, saveToLocalStorage, loadFromLocalStorage, clearLocalStorage, cleanupOldData, debounce, throttle, measurePerformance, asyncMeasurePerformance, createEventEmitter, generateId, isValidConfig, } from './utils/browserUtils.js';
|
|
13
|
+
export const VERSION = '0.1.0';
|
|
14
|
+
export function createManneriDetector(config) {
|
|
15
|
+
return new ManneriDetector(config);
|
|
16
|
+
}
|
|
17
|
+
import { ConversationAnalyzer } from './core/ConversationAnalyzer.js';
|
|
18
|
+
export function createConversationAnalyzer(options) {
|
|
19
|
+
return new ConversationAnalyzer(options);
|
|
20
|
+
}
|
|
21
|
+
import { PromptGenerator } from './generators/PromptGenerator.js';
|
|
22
|
+
export function createPromptGenerator(language, customPrompts) {
|
|
23
|
+
return new PromptGenerator(language, customPrompts);
|
|
24
|
+
}
|
|
25
|
+
import { ManneriDetector } from './core/ManneriDetector.js';
|
|
26
|
+
export default ManneriDetector;
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAgBlE,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,+BAA+B;AAC/B,OAAO,EAAE,+BAA+B,EAAE,MAAM,kDAAkD,CAAC;AAOnG,OAAO,EACL,uBAAuB,EACvB,eAAe,EACf,aAAa,EACb,QAAQ,EACR,cAAc,EACd,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,EAClB,UAAU,EACV,aAAa,GACd,MAAM,yBAAyB,CAAC;AAEjC,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,MAAM,UAAU,qBAAqB,CACnC,MAA0D;IAE1D,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC;AAED,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAEtE,MAAM,UAAU,0BAA0B,CACxC,OAEC;IAED,OAAO,IAAI,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAElE,MAAM,UAAU,qBAAqB,CACnC,QAAiB,EACjB,aAAsE;IAEtE,OAAO,IAAI,eAAe,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;AACtD,CAAC;AAED,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { PersistenceProvider } from '../types/persistence.js';
|
|
2
|
+
import type { StorageData } from '../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* LocalStorage-based persistence provider
|
|
5
|
+
*
|
|
6
|
+
* Uses browser's localStorage to persist manneri data.
|
|
7
|
+
* Only works in browser environments.
|
|
8
|
+
*/
|
|
9
|
+
export declare class LocalStoragePersistenceProvider implements PersistenceProvider {
|
|
10
|
+
private readonly storageKey;
|
|
11
|
+
private readonly version;
|
|
12
|
+
constructor(options?: {
|
|
13
|
+
storageKey?: string;
|
|
14
|
+
version?: string;
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* Save data to localStorage
|
|
18
|
+
*/
|
|
19
|
+
save(data: StorageData): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Load data from localStorage
|
|
22
|
+
*/
|
|
23
|
+
load(): StorageData | null;
|
|
24
|
+
/**
|
|
25
|
+
* Clear all data from localStorage
|
|
26
|
+
*/
|
|
27
|
+
clear(): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Clean up old data from localStorage
|
|
30
|
+
*/
|
|
31
|
+
cleanup(maxAge: number): number;
|
|
32
|
+
/**
|
|
33
|
+
* Check if localStorage is available
|
|
34
|
+
*/
|
|
35
|
+
isAvailable(): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Get storage info
|
|
38
|
+
*/
|
|
39
|
+
getStorageInfo(): {
|
|
40
|
+
key: string;
|
|
41
|
+
version: string;
|
|
42
|
+
available: boolean;
|
|
43
|
+
hasData: boolean;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { saveToLocalStorage, loadFromLocalStorage, clearLocalStorage, isBrowserEnvironment, } from '../utils/browserUtils.js';
|
|
2
|
+
/**
|
|
3
|
+
* LocalStorage-based persistence provider
|
|
4
|
+
*
|
|
5
|
+
* Uses browser's localStorage to persist manneri data.
|
|
6
|
+
* Only works in browser environments.
|
|
7
|
+
*/
|
|
8
|
+
export class LocalStoragePersistenceProvider {
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
this.storageKey = options.storageKey || 'manneri_data';
|
|
11
|
+
this.version = options.version || '1.0.0';
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Save data to localStorage
|
|
15
|
+
*/
|
|
16
|
+
save(data) {
|
|
17
|
+
if (!isBrowserEnvironment()) {
|
|
18
|
+
console.warn('LocalStoragePersistenceProvider: localStorage not available');
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return saveToLocalStorage(data, this.storageKey);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Load data from localStorage
|
|
25
|
+
*/
|
|
26
|
+
load() {
|
|
27
|
+
if (!isBrowserEnvironment()) {
|
|
28
|
+
console.warn('LocalStoragePersistenceProvider: localStorage not available');
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
return loadFromLocalStorage(this.storageKey);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Clear all data from localStorage
|
|
35
|
+
*/
|
|
36
|
+
clear() {
|
|
37
|
+
if (!isBrowserEnvironment()) {
|
|
38
|
+
console.warn('LocalStoragePersistenceProvider: localStorage not available');
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
return clearLocalStorage(this.storageKey);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Clean up old data from localStorage
|
|
45
|
+
*/
|
|
46
|
+
cleanup(maxAge) {
|
|
47
|
+
if (!isBrowserEnvironment()) {
|
|
48
|
+
console.warn('LocalStoragePersistenceProvider: localStorage not available');
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
const data = loadFromLocalStorage(this.storageKey);
|
|
52
|
+
if (!data)
|
|
53
|
+
return 0;
|
|
54
|
+
const now = Date.now();
|
|
55
|
+
const cutoff = now - maxAge;
|
|
56
|
+
const originalPatterns = data.patterns.length;
|
|
57
|
+
const originalInterventions = data.interventions.length;
|
|
58
|
+
const cleanedPatterns = data.patterns.filter((pattern) => pattern.lastSeen > cutoff);
|
|
59
|
+
const cleanedInterventions = data.interventions.filter((timestamp) => timestamp > cutoff);
|
|
60
|
+
const removedCount = originalPatterns -
|
|
61
|
+
cleanedPatterns.length +
|
|
62
|
+
(originalInterventions - cleanedInterventions.length);
|
|
63
|
+
if (removedCount > 0) {
|
|
64
|
+
const cleanedData = {
|
|
65
|
+
...data,
|
|
66
|
+
patterns: cleanedPatterns,
|
|
67
|
+
interventions: cleanedInterventions,
|
|
68
|
+
lastCleanup: now,
|
|
69
|
+
};
|
|
70
|
+
saveToLocalStorage(cleanedData, this.storageKey);
|
|
71
|
+
}
|
|
72
|
+
return removedCount;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Check if localStorage is available
|
|
76
|
+
*/
|
|
77
|
+
isAvailable() {
|
|
78
|
+
return isBrowserEnvironment();
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get storage info
|
|
82
|
+
*/
|
|
83
|
+
getStorageInfo() {
|
|
84
|
+
const available = this.isAvailable();
|
|
85
|
+
let hasData = false;
|
|
86
|
+
if (available) {
|
|
87
|
+
try {
|
|
88
|
+
hasData = localStorage.getItem(this.storageKey) !== null;
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
hasData = false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
key: this.storageKey,
|
|
96
|
+
version: this.version,
|
|
97
|
+
available,
|
|
98
|
+
hasData,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=LocalStoragePersistenceProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalStoragePersistenceProvider.js","sourceRoot":"","sources":["../../src/persistence/LocalStoragePersistenceProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/persistence/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,+BAA+B,EAAE,MAAM,sCAAsC,CAAC"}
|