@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,114 @@
|
|
|
1
|
+
export interface Message {
|
|
2
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
3
|
+
content: string;
|
|
4
|
+
timestamp?: number;
|
|
5
|
+
}
|
|
6
|
+
import type { LocalizedPrompts } from './prompts.js';
|
|
7
|
+
export interface ManneriConfig {
|
|
8
|
+
similarityThreshold: number;
|
|
9
|
+
repetitionLimit: number;
|
|
10
|
+
lookbackWindow: number;
|
|
11
|
+
interventionCooldown: number;
|
|
12
|
+
minMessageLength: number;
|
|
13
|
+
excludeKeywords: string[];
|
|
14
|
+
enableTopicTracking: boolean;
|
|
15
|
+
enableKeywordAnalysis: boolean;
|
|
16
|
+
debugMode: boolean;
|
|
17
|
+
enableAiPromptGeneration: boolean;
|
|
18
|
+
aiPromptGenerationProvider: 'openai' | 'gemini' | 'default';
|
|
19
|
+
aiPromptGenerationModel?: string;
|
|
20
|
+
language?: string;
|
|
21
|
+
customPrompts?: Partial<LocalizedPrompts>;
|
|
22
|
+
}
|
|
23
|
+
export interface SimilarityResult {
|
|
24
|
+
score: number;
|
|
25
|
+
isRepeated: boolean;
|
|
26
|
+
matchedMessages: Message[];
|
|
27
|
+
}
|
|
28
|
+
export interface ConversationPattern {
|
|
29
|
+
id: string;
|
|
30
|
+
pattern: string;
|
|
31
|
+
frequency: number;
|
|
32
|
+
firstSeen: number;
|
|
33
|
+
lastSeen: number;
|
|
34
|
+
messages: Message[];
|
|
35
|
+
}
|
|
36
|
+
export interface TopicInfo {
|
|
37
|
+
keywords: string[];
|
|
38
|
+
score: number;
|
|
39
|
+
category: string;
|
|
40
|
+
confidence: number;
|
|
41
|
+
}
|
|
42
|
+
export interface AnalysisResult {
|
|
43
|
+
similarity: SimilarityResult;
|
|
44
|
+
topics: TopicInfo[];
|
|
45
|
+
patterns: ConversationPattern[];
|
|
46
|
+
shouldIntervene: boolean;
|
|
47
|
+
interventionReason: string;
|
|
48
|
+
lastIntervention: number;
|
|
49
|
+
}
|
|
50
|
+
export interface DiversificationPrompt {
|
|
51
|
+
content: string;
|
|
52
|
+
type: 'topic_change' | 'pattern_break' | 'keyword_shift';
|
|
53
|
+
priority: 'low' | 'medium' | 'high';
|
|
54
|
+
context: string;
|
|
55
|
+
}
|
|
56
|
+
export interface AiProviderConfig {
|
|
57
|
+
provider: 'openai' | 'gemini';
|
|
58
|
+
model: string;
|
|
59
|
+
apiKey: string;
|
|
60
|
+
}
|
|
61
|
+
export interface TextAnalysisOptions {
|
|
62
|
+
minWordLength: number;
|
|
63
|
+
maxNgrams: number;
|
|
64
|
+
includeStopWords: boolean;
|
|
65
|
+
caseSensitive: boolean;
|
|
66
|
+
language: 'ja' | 'en' | 'auto';
|
|
67
|
+
}
|
|
68
|
+
export interface StorageData {
|
|
69
|
+
patterns: ConversationPattern[];
|
|
70
|
+
interventions: number[];
|
|
71
|
+
settings: Partial<ManneriConfig>;
|
|
72
|
+
lastCleanup: number;
|
|
73
|
+
}
|
|
74
|
+
export interface ManneriEvent {
|
|
75
|
+
pattern_detected: AnalysisResult;
|
|
76
|
+
intervention_triggered: DiversificationPrompt;
|
|
77
|
+
topic_changed: {
|
|
78
|
+
oldTopics: string[];
|
|
79
|
+
newTopics: string[];
|
|
80
|
+
};
|
|
81
|
+
similarity_calculated: {
|
|
82
|
+
score: number;
|
|
83
|
+
threshold: number;
|
|
84
|
+
};
|
|
85
|
+
config_updated: Partial<ManneriConfig>;
|
|
86
|
+
storage_cleaned: {
|
|
87
|
+
removedItems: number;
|
|
88
|
+
};
|
|
89
|
+
save_success: {
|
|
90
|
+
timestamp: number;
|
|
91
|
+
};
|
|
92
|
+
save_error: {
|
|
93
|
+
error: Error;
|
|
94
|
+
};
|
|
95
|
+
load_success: {
|
|
96
|
+
data: StorageData;
|
|
97
|
+
timestamp: number;
|
|
98
|
+
};
|
|
99
|
+
load_error: {
|
|
100
|
+
error: Error;
|
|
101
|
+
};
|
|
102
|
+
cleanup_completed: {
|
|
103
|
+
removedItems: number;
|
|
104
|
+
timestamp: number;
|
|
105
|
+
};
|
|
106
|
+
cleanup_error: {
|
|
107
|
+
error: Error;
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
export type ManneriEventHandler<T = unknown> = (data: T) => void;
|
|
111
|
+
export declare const DEFAULT_MANNERI_CONFIG: ManneriConfig;
|
|
112
|
+
export type { PromptTemplates, LocalizedPrompts, } from './prompts.js';
|
|
113
|
+
export type { PersistenceProvider, PersistenceConfig, PersistenceEvents, } from './persistence.js';
|
|
114
|
+
export { getPromptTemplate, overridePrompts } from './prompts.js';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export const DEFAULT_MANNERI_CONFIG = {
|
|
2
|
+
similarityThreshold: 0.75,
|
|
3
|
+
repetitionLimit: 3,
|
|
4
|
+
lookbackWindow: 10,
|
|
5
|
+
interventionCooldown: 300000,
|
|
6
|
+
minMessageLength: 10,
|
|
7
|
+
excludeKeywords: [
|
|
8
|
+
'はい',
|
|
9
|
+
'そうですね',
|
|
10
|
+
'そうです',
|
|
11
|
+
'いいえ',
|
|
12
|
+
'yes',
|
|
13
|
+
'no',
|
|
14
|
+
'ok',
|
|
15
|
+
'okay',
|
|
16
|
+
],
|
|
17
|
+
enableTopicTracking: true,
|
|
18
|
+
enableKeywordAnalysis: true,
|
|
19
|
+
debugMode: false,
|
|
20
|
+
enableAiPromptGeneration: false,
|
|
21
|
+
aiPromptGenerationProvider: 'default',
|
|
22
|
+
aiPromptGenerationModel: undefined,
|
|
23
|
+
language: 'ja',
|
|
24
|
+
customPrompts: undefined,
|
|
25
|
+
};
|
|
26
|
+
// Re-export utility functions
|
|
27
|
+
export { getPromptTemplate, overridePrompts } from './prompts.js';
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAuGA,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,mBAAmB,EAAE,IAAI;IACzB,eAAe,EAAE,CAAC;IAClB,cAAc,EAAE,EAAE;IAClB,oBAAoB,EAAE,MAAM;IAC5B,gBAAgB,EAAE,EAAE;IACpB,eAAe,EAAE;QACf,IAAI;QACJ,OAAO;QACP,MAAM;QACN,KAAK;QACL,KAAK;QACL,IAAI;QACJ,IAAI;QACJ,MAAM;KACP;IACD,mBAAmB,EAAE,IAAI;IACzB,qBAAqB,EAAE,IAAI;IAC3B,SAAS,EAAE,KAAK;IAChB,wBAAwB,EAAE,KAAK;IAC/B,0BAA0B,EAAE,SAAS;IACrC,uBAAuB,EAAE,SAAS;IAClC,QAAQ,EAAE,IAAI;IACd,aAAa,EAAE,SAAS;CACzB,CAAC;AAeF,8BAA8B;AAC9B,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { StorageData } from './index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Interface for persistence providers
|
|
4
|
+
* Allows custom storage implementations (localStorage, IndexedDB, databases, etc.)
|
|
5
|
+
*/
|
|
6
|
+
export interface PersistenceProvider {
|
|
7
|
+
/**
|
|
8
|
+
* Save data to storage
|
|
9
|
+
* @param data Data to save
|
|
10
|
+
* @returns Promise<boolean> or boolean indicating success
|
|
11
|
+
*/
|
|
12
|
+
save(data: StorageData): Promise<boolean> | boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Load data from storage
|
|
15
|
+
* @returns Promise<StorageData | null> or StorageData | null
|
|
16
|
+
*/
|
|
17
|
+
load(): Promise<StorageData | null> | StorageData | null;
|
|
18
|
+
/**
|
|
19
|
+
* Clear all data from storage
|
|
20
|
+
* @returns Promise<boolean> or boolean indicating success
|
|
21
|
+
*/
|
|
22
|
+
clear(): Promise<boolean> | boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Clean up old data (optional)
|
|
25
|
+
* @param maxAge Maximum age in milliseconds
|
|
26
|
+
* @returns Promise<number> or number of items removed
|
|
27
|
+
*/
|
|
28
|
+
cleanup?(maxAge: number): Promise<number> | number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Configuration for persistence
|
|
32
|
+
*/
|
|
33
|
+
export interface PersistenceConfig {
|
|
34
|
+
/**
|
|
35
|
+
* Persistence provider instance
|
|
36
|
+
*/
|
|
37
|
+
provider: PersistenceProvider;
|
|
38
|
+
/**
|
|
39
|
+
* Auto-save interval in milliseconds (0 = disabled)
|
|
40
|
+
* @default 0
|
|
41
|
+
*/
|
|
42
|
+
autoSaveInterval?: number;
|
|
43
|
+
/**
|
|
44
|
+
* Auto-cleanup interval in milliseconds (0 = disabled)
|
|
45
|
+
* @default 0
|
|
46
|
+
*/
|
|
47
|
+
autoCleanupInterval?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Maximum age for cleanup in milliseconds
|
|
50
|
+
* @default 7 * 24 * 60 * 60 * 1000 (7 days)
|
|
51
|
+
*/
|
|
52
|
+
maxAge?: number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Storage event types
|
|
56
|
+
*/
|
|
57
|
+
export interface PersistenceEvents {
|
|
58
|
+
save_success: {
|
|
59
|
+
timestamp: number;
|
|
60
|
+
};
|
|
61
|
+
save_error: {
|
|
62
|
+
error: Error;
|
|
63
|
+
};
|
|
64
|
+
load_success: {
|
|
65
|
+
data: StorageData;
|
|
66
|
+
timestamp: number;
|
|
67
|
+
};
|
|
68
|
+
load_error: {
|
|
69
|
+
error: Error;
|
|
70
|
+
};
|
|
71
|
+
cleanup_completed: {
|
|
72
|
+
removedItems: number;
|
|
73
|
+
timestamp: number;
|
|
74
|
+
};
|
|
75
|
+
cleanup_error: {
|
|
76
|
+
error: Error;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence.js","sourceRoot":"","sources":["../../src/types/persistence.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt template types for intervention
|
|
3
|
+
*/
|
|
4
|
+
export interface PromptTemplates {
|
|
5
|
+
intervention: string[];
|
|
6
|
+
}
|
|
7
|
+
export interface LocalizedPrompts {
|
|
8
|
+
[language: string]: PromptTemplates;
|
|
9
|
+
}
|
|
10
|
+
export interface PromptConfig {
|
|
11
|
+
language?: string;
|
|
12
|
+
customPrompts?: Partial<LocalizedPrompts>;
|
|
13
|
+
}
|
|
14
|
+
export type SupportedLanguage = 'ja' | 'en' | string;
|
|
15
|
+
/**
|
|
16
|
+
* Get prompt template for specific language and path
|
|
17
|
+
*/
|
|
18
|
+
export declare function getPromptTemplate(prompts: LocalizedPrompts, language: string, index?: number): string;
|
|
19
|
+
/**
|
|
20
|
+
* Override default prompts with custom prompts where provided
|
|
21
|
+
*/
|
|
22
|
+
export declare function overridePrompts(defaultPrompts: LocalizedPrompts, customPrompts?: Partial<LocalizedPrompts>): LocalizedPrompts;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt template types for intervention
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Get prompt template for specific language and path
|
|
6
|
+
*/
|
|
7
|
+
export function getPromptTemplate(prompts, language, index) {
|
|
8
|
+
const langPrompts = prompts[language] || prompts.en;
|
|
9
|
+
if (!langPrompts || !langPrompts.intervention) {
|
|
10
|
+
return 'Please change the topic and talk about something new.';
|
|
11
|
+
}
|
|
12
|
+
if (index !== undefined && langPrompts.intervention[index]) {
|
|
13
|
+
return langPrompts.intervention[index];
|
|
14
|
+
}
|
|
15
|
+
// Return random intervention prompt
|
|
16
|
+
const randomIndex = Math.floor(Math.random() * langPrompts.intervention.length);
|
|
17
|
+
return langPrompts.intervention[randomIndex];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Override default prompts with custom prompts where provided
|
|
21
|
+
*/
|
|
22
|
+
export function overridePrompts(defaultPrompts, customPrompts) {
|
|
23
|
+
if (!customPrompts)
|
|
24
|
+
return defaultPrompts;
|
|
25
|
+
const merged = { ...defaultPrompts };
|
|
26
|
+
for (const [lang, templates] of Object.entries(customPrompts)) {
|
|
27
|
+
if (templates?.intervention) {
|
|
28
|
+
merged[lang] = {
|
|
29
|
+
...merged[lang], // Preserve default prompts
|
|
30
|
+
...templates, // Override with custom prompts
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return merged;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/types/prompts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiBH;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAAyB,EACzB,QAAgB,EAChB,KAAc;IAEd,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC;IACpD,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC;QAC9C,OAAO,uDAAuD,CAAC;IACjE,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,IAAI,WAAW,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3D,OAAO,WAAW,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,oCAAoC;IACpC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAC5B,IAAI,CAAC,MAAM,EAAE,GAAG,WAAW,CAAC,YAAY,CAAC,MAAM,CAChD,CAAC;IACF,OAAO,WAAW,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,cAAgC,EAChC,aAAyC;IAEzC,IAAI,CAAC,aAAa;QAAE,OAAO,cAAc,CAAC;IAE1C,MAAM,MAAM,GAAqB,EAAE,GAAG,cAAc,EAAE,CAAC;IAEvD,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9D,IAAI,SAAS,EAAE,YAAY,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,GAAG;gBACb,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,2BAA2B;gBAC5C,GAAG,SAAS,EAAE,+BAA+B;aAC9C,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { StorageData, ManneriConfig } from '../types/index.js';
|
|
2
|
+
export declare function isBrowserEnvironment(): boolean;
|
|
3
|
+
export declare function saveToLocalStorage(data: StorageData, storageKey?: string): boolean;
|
|
4
|
+
export declare function loadFromLocalStorage(storageKey?: string): StorageData | null;
|
|
5
|
+
export declare function clearLocalStorage(storageKey?: string): boolean;
|
|
6
|
+
export declare function getStorageSize(storageKey?: string): number;
|
|
7
|
+
export declare function cleanupOldData(storageKey?: string, maxAge?: number): boolean;
|
|
8
|
+
export declare function debounce<T extends (...args: unknown[]) => void>(func: T, wait: number, immediate?: boolean): T;
|
|
9
|
+
export declare function throttle<T extends (...args: unknown[]) => void>(func: T, limit: number): T;
|
|
10
|
+
export declare function createWorkerFunction(fn: () => void): Worker | null;
|
|
11
|
+
export declare function measurePerformance<T>(name: string, fn: () => T, enableLogging?: boolean): T;
|
|
12
|
+
export declare function asyncMeasurePerformance<T>(name: string, fn: () => Promise<T>, enableLogging?: boolean): Promise<T>;
|
|
13
|
+
export declare function createEventEmitter<EventMap extends Record<string, unknown>>(): {
|
|
14
|
+
on<K extends keyof EventMap>(event: K, listener: (data: EventMap[K]) => void): void;
|
|
15
|
+
off<K extends keyof EventMap>(event: K, listener: (data: EventMap[K]) => void): void;
|
|
16
|
+
emit<K extends keyof EventMap>(event: K, data: EventMap[K]): void;
|
|
17
|
+
removeAllListeners(): void;
|
|
18
|
+
};
|
|
19
|
+
export declare function generateId(): string;
|
|
20
|
+
export declare function isValidConfig(config: unknown): config is ManneriConfig;
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
const STORAGE_KEY = 'manneri_data';
|
|
2
|
+
const STORAGE_VERSION = '1.0.0';
|
|
3
|
+
export function isBrowserEnvironment() {
|
|
4
|
+
return typeof window !== 'undefined' && typeof localStorage !== 'undefined';
|
|
5
|
+
}
|
|
6
|
+
export function saveToLocalStorage(data, storageKey) {
|
|
7
|
+
if (!isBrowserEnvironment())
|
|
8
|
+
return false;
|
|
9
|
+
try {
|
|
10
|
+
const storageData = {
|
|
11
|
+
version: STORAGE_VERSION,
|
|
12
|
+
timestamp: Date.now(),
|
|
13
|
+
data,
|
|
14
|
+
};
|
|
15
|
+
localStorage.setItem(storageKey || STORAGE_KEY, JSON.stringify(storageData));
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
console.warn('Failed to save manneri data to localStorage:', error);
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function loadFromLocalStorage(storageKey) {
|
|
24
|
+
if (!isBrowserEnvironment())
|
|
25
|
+
return null;
|
|
26
|
+
try {
|
|
27
|
+
const item = localStorage.getItem(storageKey || STORAGE_KEY);
|
|
28
|
+
if (!item)
|
|
29
|
+
return null;
|
|
30
|
+
const storageData = JSON.parse(item);
|
|
31
|
+
if (storageData.version !== STORAGE_VERSION) {
|
|
32
|
+
console.warn('Manneri storage version mismatch, clearing data');
|
|
33
|
+
clearLocalStorage(storageKey);
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
return storageData.data;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
console.warn('Failed to load manneri data from localStorage:', error);
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export function clearLocalStorage(storageKey) {
|
|
44
|
+
if (!isBrowserEnvironment())
|
|
45
|
+
return false;
|
|
46
|
+
try {
|
|
47
|
+
localStorage.removeItem(storageKey || STORAGE_KEY);
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.warn('Failed to clear manneri data from localStorage:', error);
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export function getStorageSize(storageKey) {
|
|
56
|
+
if (!isBrowserEnvironment())
|
|
57
|
+
return 0;
|
|
58
|
+
try {
|
|
59
|
+
const item = localStorage.getItem(storageKey || STORAGE_KEY);
|
|
60
|
+
return item ? new Blob([item]).size : 0;
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export function cleanupOldData(storageKey, maxAge = 24 * 60 * 60 * 1000) {
|
|
67
|
+
const data = loadFromLocalStorage(storageKey);
|
|
68
|
+
if (!data)
|
|
69
|
+
return false;
|
|
70
|
+
const now = Date.now();
|
|
71
|
+
const cutoff = now - maxAge;
|
|
72
|
+
const cleanedPatterns = data.patterns.filter((pattern) => pattern.lastSeen > cutoff);
|
|
73
|
+
const cleanedInterventions = data.interventions.filter((timestamp) => timestamp > cutoff);
|
|
74
|
+
const cleanedData = {
|
|
75
|
+
...data,
|
|
76
|
+
patterns: cleanedPatterns,
|
|
77
|
+
interventions: cleanedInterventions,
|
|
78
|
+
lastCleanup: now,
|
|
79
|
+
};
|
|
80
|
+
return saveToLocalStorage(cleanedData, storageKey);
|
|
81
|
+
}
|
|
82
|
+
export function debounce(func, wait, immediate = false) {
|
|
83
|
+
let timeout = null;
|
|
84
|
+
return ((...args) => {
|
|
85
|
+
const later = () => {
|
|
86
|
+
timeout = null;
|
|
87
|
+
if (!immediate)
|
|
88
|
+
func(...args);
|
|
89
|
+
};
|
|
90
|
+
const callNow = immediate && !timeout;
|
|
91
|
+
if (timeout)
|
|
92
|
+
clearTimeout(timeout);
|
|
93
|
+
timeout = setTimeout(later, wait);
|
|
94
|
+
if (callNow)
|
|
95
|
+
func(...args);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
export function throttle(func, limit) {
|
|
99
|
+
let inThrottle = false;
|
|
100
|
+
return ((...args) => {
|
|
101
|
+
if (!inThrottle) {
|
|
102
|
+
func(...args);
|
|
103
|
+
inThrottle = true;
|
|
104
|
+
setTimeout(() => {
|
|
105
|
+
inThrottle = false;
|
|
106
|
+
}, limit);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
export function createWorkerFunction(fn) {
|
|
111
|
+
if (!isBrowserEnvironment() || typeof Worker === 'undefined')
|
|
112
|
+
return null;
|
|
113
|
+
try {
|
|
114
|
+
const functionString = fn.toString();
|
|
115
|
+
const blob = new Blob([`(${functionString})()`], {
|
|
116
|
+
type: 'application/javascript',
|
|
117
|
+
});
|
|
118
|
+
const url = URL.createObjectURL(blob);
|
|
119
|
+
const worker = new Worker(url);
|
|
120
|
+
worker.addEventListener('error', () => {
|
|
121
|
+
URL.revokeObjectURL(url);
|
|
122
|
+
});
|
|
123
|
+
return worker;
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
console.warn('Failed to create worker:', error);
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
export function measurePerformance(name, fn, enableLogging = false) {
|
|
131
|
+
const start = performance.now();
|
|
132
|
+
const result = fn();
|
|
133
|
+
const end = performance.now();
|
|
134
|
+
if (enableLogging) {
|
|
135
|
+
console.log(`[Manneri] ${name}: ${(end - start).toFixed(2)}ms`);
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
export function asyncMeasurePerformance(name, fn, enableLogging = false) {
|
|
140
|
+
const start = performance.now();
|
|
141
|
+
return fn().then((result) => {
|
|
142
|
+
const end = performance.now();
|
|
143
|
+
if (enableLogging) {
|
|
144
|
+
console.log(`[Manneri] ${name}: ${(end - start).toFixed(2)}ms`);
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
export function createEventEmitter() {
|
|
150
|
+
const listeners = new Map();
|
|
151
|
+
return {
|
|
152
|
+
on(event, listener) {
|
|
153
|
+
const eventKey = String(event);
|
|
154
|
+
if (!listeners.has(eventKey)) {
|
|
155
|
+
listeners.set(eventKey, new Set());
|
|
156
|
+
}
|
|
157
|
+
listeners.get(eventKey)?.add(listener);
|
|
158
|
+
},
|
|
159
|
+
off(event, listener) {
|
|
160
|
+
const eventKey = String(event);
|
|
161
|
+
const eventListeners = listeners.get(eventKey);
|
|
162
|
+
if (eventListeners) {
|
|
163
|
+
eventListeners.delete(listener);
|
|
164
|
+
if (eventListeners.size === 0) {
|
|
165
|
+
listeners.delete(eventKey);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
emit(event, data) {
|
|
170
|
+
const eventKey = String(event);
|
|
171
|
+
const eventListeners = listeners.get(eventKey);
|
|
172
|
+
if (eventListeners) {
|
|
173
|
+
for (const listener of eventListeners) {
|
|
174
|
+
try {
|
|
175
|
+
listener(data);
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
console.error(`Error in event listener for ${String(event)}:`, error);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
removeAllListeners() {
|
|
184
|
+
listeners.clear();
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
export function generateId() {
|
|
189
|
+
return Math.random().toString(36).substr(2, 9) + Date.now().toString(36);
|
|
190
|
+
}
|
|
191
|
+
export function isValidConfig(config) {
|
|
192
|
+
if (typeof config !== 'object' || config === null) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
const c = config;
|
|
196
|
+
return (typeof c.similarityThreshold === 'number' &&
|
|
197
|
+
typeof c.repetitionLimit === 'number' &&
|
|
198
|
+
typeof c.lookbackWindow === 'number' &&
|
|
199
|
+
typeof c.interventionCooldown === 'number' &&
|
|
200
|
+
typeof c.minMessageLength === 'number' &&
|
|
201
|
+
Array.isArray(c.excludeKeywords) &&
|
|
202
|
+
typeof c.enableTopicTracking === 'boolean' &&
|
|
203
|
+
typeof c.enableKeywordAnalysis === 'boolean' &&
|
|
204
|
+
typeof c.debugMode === 'boolean');
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=browserUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browserUtils.js","sourceRoot":"","sources":["../../src/utils/browserUtils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TextAnalysisOptions } from '../types/index.js';
|
|
2
|
+
export declare function normalizeText(text: string, options?: Partial<TextAnalysisOptions>): string;
|
|
3
|
+
export declare function containsJapanese(text: string): boolean;
|
|
4
|
+
export declare function tokenize(text: string, options?: Partial<TextAnalysisOptions>): string[];
|
|
5
|
+
export declare function generateNgrams(tokens: string[], n: number): string[];
|
|
6
|
+
export declare function calculateJaccardSimilarity(set1: Set<string>, set2: Set<string>): number;
|
|
7
|
+
export declare function calculateCosineSimilarity(vector1: number[], vector2: number[]): number;
|
|
8
|
+
export declare function createTfIdfVector(tokens: string[], vocabulary: string[], documentFrequencies: Map<string, number>, totalDocuments: number): number[];
|
|
9
|
+
export declare function extractKeywords(text: string, options?: Partial<TextAnalysisOptions>): string[];
|
|
10
|
+
export declare function calculateTextSimilarity(text1: string, text2: string, options?: Partial<TextAnalysisOptions>): number;
|