empathai-core 0.2.0 → 0.2.2
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.md +128 -15
- package/dist/index.d.ts +53 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +121 -29
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,15 +13,9 @@
|
|
|
13
13
|
`empathai-core` analyzes user interaction signals (mouse movement, typing rhythm, clicks) and returns inferred emotional states (e.g. `focused`, `frustrated`, `bored`, `neutral`) together with a basic confidence score.
|
|
14
14
|
It is intentionally **privacy-first** — no camera/mic required.
|
|
15
15
|
|
|
16
|
-
> **EmpathAI Core** is a privacy-first, non-intrusive **emotion signal engine** for web applications.
|
|
17
|
-
It detects user emotional states in real time using **behavioral signals** such as mouse movement and typing patterns.
|
|
18
|
-
|
|
19
|
-
⚠️ This package is **NOT a recommendation engine** and **NOT an ML model**.
|
|
20
|
-
It is a **foundational signal layer** designed to be consumed by higher-level systems (AI, analytics, UX, decision engines).
|
|
21
|
-
|
|
22
16
|
---
|
|
23
17
|
|
|
24
|
-
##
|
|
18
|
+
## What EmpathAI Core Does
|
|
25
19
|
|
|
26
20
|
- Captures **non-intrusive user behavior signals**
|
|
27
21
|
- Infers **basic emotional states** (deterministic v1)
|
|
@@ -32,21 +26,140 @@ It is a **foundational signal layer** designed to be consumed by higher-level sy
|
|
|
32
26
|
|
|
33
27
|
---
|
|
34
28
|
|
|
35
|
-
##
|
|
29
|
+
## What EmpathAI Core Does NOT Do
|
|
36
30
|
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
- ❌ No emotion prediction via ML (yet)
|
|
41
|
-
- ❌ No recommendations or decisions
|
|
31
|
+
- No camera access
|
|
32
|
+
- No microphone access
|
|
33
|
+
- No personal data collection
|
|
42
34
|
|
|
43
35
|
EmpathAI Core provides **signals**, not decisions.
|
|
44
36
|
|
|
45
37
|
---
|
|
46
38
|
|
|
47
|
-
##
|
|
48
|
-
|
|
39
|
+
## Installation
|
|
49
40
|
```bash
|
|
50
41
|
npm install empathai-core
|
|
51
42
|
# or
|
|
52
43
|
pnpm add empathai-core
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Usage Examples
|
|
49
|
+
|
|
50
|
+
### React (Recommended for React Apps)
|
|
51
|
+
```jsx
|
|
52
|
+
import { useEmpathAI } from 'empathai-core/hooks';
|
|
53
|
+
|
|
54
|
+
function App() {
|
|
55
|
+
const { emotion } = useEmpathAI({
|
|
56
|
+
enableMouseTracking: true,
|
|
57
|
+
enableKeyboardTracking: true,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<div>
|
|
62
|
+
<h2>Current emotion</h2>
|
|
63
|
+
<p>{emotion.type}</p>
|
|
64
|
+
<p>Confidence: {emotion.confidence}</p>
|
|
65
|
+
</div>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default App;
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
### JavaScript (Vanilla JS)
|
|
75
|
+
```javascript
|
|
76
|
+
import { createEmpathAI } from 'empathai-core';
|
|
77
|
+
|
|
78
|
+
const empathAI = createEmpathAI({
|
|
79
|
+
onEmotionDetected: (emotion) => {
|
|
80
|
+
console.log('Emotion detected:', emotion);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
empathAI.init();
|
|
85
|
+
|
|
86
|
+
// Optional cleanup
|
|
87
|
+
window.addEventListener('beforeunload', () => {
|
|
88
|
+
empathAI.destroy();
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
### Java Backend with Web Frontend
|
|
95
|
+
|
|
96
|
+
**Frontend (JavaScript)**
|
|
97
|
+
```javascript
|
|
98
|
+
import { createEmpathAI } from 'empathai-core';
|
|
99
|
+
|
|
100
|
+
const empathAI = createEmpathAI({
|
|
101
|
+
onEmotionDetected: (emotion) => {
|
|
102
|
+
fetch('/api/emotion', {
|
|
103
|
+
method: 'POST',
|
|
104
|
+
headers: { 'Content-Type': 'application/json' },
|
|
105
|
+
body: JSON.stringify(emotion),
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
empathAI.init();
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Backend (Spring Boot example)**
|
|
114
|
+
```java
|
|
115
|
+
@RestController
|
|
116
|
+
@RequestMapping("/api")
|
|
117
|
+
public class EmotionController {
|
|
118
|
+
|
|
119
|
+
@PostMapping("/emotion")
|
|
120
|
+
public ResponseEntity<Void> receiveEmotion(@RequestBody EmotionPayload payload) {
|
|
121
|
+
// Store, analyze, or react to emotion signal
|
|
122
|
+
return ResponseEntity.ok().build();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
### Python Backend with Web Frontend
|
|
130
|
+
|
|
131
|
+
**Frontend (JavaScript)**
|
|
132
|
+
```javascript
|
|
133
|
+
import { createEmpathAI } from 'empathai-core';
|
|
134
|
+
|
|
135
|
+
const empathAI = createEmpathAI({
|
|
136
|
+
onEmotionDetected: (emotion) => {
|
|
137
|
+
fetch('/emotion', {
|
|
138
|
+
method: 'POST',
|
|
139
|
+
headers: { 'Content-Type': 'application/json' },
|
|
140
|
+
body: JSON.stringify(emotion),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
empathAI.init();
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Backend (Flask example)**
|
|
149
|
+
```python
|
|
150
|
+
from flask import Flask, request
|
|
151
|
+
|
|
152
|
+
app = Flask(__name__)
|
|
153
|
+
|
|
154
|
+
@app.route("/emotion", methods=["POST"])
|
|
155
|
+
def receive_emotion():
|
|
156
|
+
data = request.json
|
|
157
|
+
# Process emotion signal
|
|
158
|
+
return "", 200
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,60 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EmotionData, EmpathAIOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Core EmpathAI engine
|
|
4
|
+
* - Behavior-signal driven
|
|
5
|
+
* - Time-window aggregated
|
|
6
|
+
* - Privacy-first
|
|
7
|
+
* - Deterministic v1 (ML-ready)
|
|
8
|
+
*/
|
|
2
9
|
export declare class EmpathAI {
|
|
3
|
-
private options
|
|
4
|
-
private
|
|
5
|
-
private
|
|
6
|
-
|
|
10
|
+
private options;
|
|
11
|
+
private currentEmotion;
|
|
12
|
+
private currentConfidence;
|
|
13
|
+
private emotionListeners;
|
|
14
|
+
private mouseSignals;
|
|
15
|
+
private keySignals;
|
|
16
|
+
private readonly SIGNAL_WINDOW_MS;
|
|
17
|
+
private readonly ANALYSIS_INTERVAL_MS;
|
|
18
|
+
private analysisTimer?;
|
|
19
|
+
private initialized;
|
|
20
|
+
constructor(options?: EmpathAIOptions);
|
|
21
|
+
/**
|
|
22
|
+
* Initialize tracking (idempotent)
|
|
23
|
+
*/
|
|
7
24
|
init(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Cleanup listeners & timers
|
|
27
|
+
*/
|
|
8
28
|
destroy(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Mouse movement tracking
|
|
31
|
+
*/
|
|
9
32
|
private handleMouseMove;
|
|
33
|
+
/**
|
|
34
|
+
* Keyboard tracking
|
|
35
|
+
*/
|
|
10
36
|
private handleKeyDown;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Core emotion inference logic
|
|
39
|
+
* (deterministic, explainable, extendable)
|
|
40
|
+
*/
|
|
41
|
+
private analyzeSignals;
|
|
42
|
+
/**
|
|
43
|
+
* Emit emotion change event
|
|
44
|
+
*/
|
|
45
|
+
private emitEmotion;
|
|
46
|
+
/**
|
|
47
|
+
* Subscribe to emotion updates
|
|
48
|
+
* Returns unsubscribe function
|
|
49
|
+
*/
|
|
50
|
+
onEmotionChange(callback: (data: EmotionData) => void): () => void;
|
|
51
|
+
/**
|
|
52
|
+
* Get current emotion snapshot
|
|
53
|
+
*/
|
|
54
|
+
getCurrentEmotion(): EmotionData;
|
|
14
55
|
}
|
|
15
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Factory method (recommended usage)
|
|
58
|
+
*/
|
|
59
|
+
export declare function createEmpathAI(options?: EmpathAIOptions): EmpathAI;
|
|
16
60
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,WAAW,EACX,eAAe,EAChB,MAAM,SAAS,CAAC;AAejB;;;;;;GAMG;AACH,qBAAa,QAAQ;IAeP,OAAO,CAAC,OAAO;IAd3B,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,iBAAiB,CAAO;IAEhC,OAAO,CAAC,gBAAgB,CAA0C;IAElE,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,UAAU,CAAmB;IAErC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAQ;IACzC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAQ;IAE7C,OAAO,CAAC,aAAa,CAAC,CAAiC;IACvD,OAAO,CAAC,WAAW,CAAS;gBAER,OAAO,GAAE,eAAoB;IAEjD;;OAEG;IACH,IAAI;IAsBJ;;OAEG;IACH,OAAO;IAgBP;;OAEG;IACH,OAAO,CAAC,eAAe,CAOrB;IAEF;;OAEG;IACH,OAAO,CAAC,aAAa,CAKnB;IAEF;;;OAGG;IACH,OAAO,CAAC,cAAc,CAqCpB;IAEF;;OAEG;IACH,OAAO,CAAC,WAAW;IAgBnB;;;OAGG;IACH,eAAe,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI;IAUrD;;OAEG;IACH,iBAAiB,IAAI,WAAW;CAOjC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,eAAe,YAEvD"}
|
package/dist/index.js
CHANGED
|
@@ -1,56 +1,148 @@
|
|
|
1
|
+
// packages/core/src/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* Core EmpathAI engine
|
|
4
|
+
* - Behavior-signal driven
|
|
5
|
+
* - Time-window aggregated
|
|
6
|
+
* - Privacy-first
|
|
7
|
+
* - Deterministic v1 (ML-ready)
|
|
8
|
+
*/
|
|
1
9
|
export class EmpathAI {
|
|
2
|
-
constructor(options) {
|
|
10
|
+
constructor(options = {}) {
|
|
3
11
|
this.options = options;
|
|
4
|
-
this.
|
|
5
|
-
this.
|
|
12
|
+
this.currentEmotion = 'neutral';
|
|
13
|
+
this.currentConfidence = 0.5;
|
|
14
|
+
this.emotionListeners = [];
|
|
15
|
+
this.mouseSignals = [];
|
|
16
|
+
this.keySignals = [];
|
|
17
|
+
this.SIGNAL_WINDOW_MS = 3000;
|
|
18
|
+
this.ANALYSIS_INTERVAL_MS = 1000;
|
|
19
|
+
this.initialized = false;
|
|
20
|
+
/**
|
|
21
|
+
* Mouse movement tracking
|
|
22
|
+
*/
|
|
6
23
|
this.handleMouseMove = (e) => {
|
|
7
|
-
// Sample rule: fast/erratic movement = frustration
|
|
8
24
|
const speed = Math.abs(e.movementX) + Math.abs(e.movementY);
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
this.updateEmotion('neutral');
|
|
14
|
-
}
|
|
25
|
+
this.mouseSignals.push({
|
|
26
|
+
speed,
|
|
27
|
+
timestamp: Date.now(),
|
|
28
|
+
});
|
|
15
29
|
};
|
|
30
|
+
/**
|
|
31
|
+
* Keyboard tracking
|
|
32
|
+
*/
|
|
16
33
|
this.handleKeyDown = (e) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
34
|
+
this.keySignals.push({
|
|
35
|
+
key: e.key,
|
|
36
|
+
timestamp: Date.now(),
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Core emotion inference logic
|
|
41
|
+
* (deterministic, explainable, extendable)
|
|
42
|
+
*/
|
|
43
|
+
this.analyzeSignals = () => {
|
|
44
|
+
const now = Date.now();
|
|
45
|
+
// Keep only recent signals
|
|
46
|
+
this.mouseSignals = this.mouseSignals.filter((s) => now - s.timestamp <= this.SIGNAL_WINDOW_MS);
|
|
47
|
+
this.keySignals = this.keySignals.filter((s) => now - s.timestamp <= this.SIGNAL_WINDOW_MS);
|
|
48
|
+
let nextEmotion = 'neutral';
|
|
49
|
+
let confidence = 0.3;
|
|
50
|
+
const avgMouseSpeed = this.mouseSignals.reduce((sum, s) => sum + s.speed, 0) /
|
|
51
|
+
(this.mouseSignals.length || 1);
|
|
52
|
+
const backspaceCount = this.keySignals.filter((k) => k.key === 'Backspace').length;
|
|
53
|
+
const typingCount = this.keySignals.length;
|
|
54
|
+
// --- Emotion inference rules (v1) ---
|
|
55
|
+
if (avgMouseSpeed > 60 && backspaceCount > 2) {
|
|
56
|
+
nextEmotion = 'frustrated';
|
|
57
|
+
confidence = 0.8;
|
|
20
58
|
}
|
|
21
|
-
else {
|
|
22
|
-
|
|
59
|
+
else if (typingCount > 15 && backspaceCount === 0) {
|
|
60
|
+
nextEmotion = 'focused';
|
|
61
|
+
confidence = 0.7;
|
|
23
62
|
}
|
|
63
|
+
else if (typingCount === 0 && this.mouseSignals.length < 3) {
|
|
64
|
+
nextEmotion = 'bored';
|
|
65
|
+
confidence = 0.6;
|
|
66
|
+
}
|
|
67
|
+
this.emitEmotion(nextEmotion, confidence);
|
|
24
68
|
};
|
|
25
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Initialize tracking (idempotent)
|
|
72
|
+
*/
|
|
26
73
|
init() {
|
|
27
|
-
if (
|
|
74
|
+
if (typeof window === 'undefined')
|
|
75
|
+
return;
|
|
76
|
+
if (this.initialized)
|
|
77
|
+
return;
|
|
78
|
+
this.initialized = true;
|
|
79
|
+
if (this.options.enableMouseTracking !== false) {
|
|
28
80
|
window.addEventListener('mousemove', this.handleMouseMove);
|
|
29
81
|
}
|
|
30
|
-
if (this.options
|
|
82
|
+
if (this.options.enableKeyboardTracking !== false) {
|
|
31
83
|
window.addEventListener('keydown', this.handleKeyDown);
|
|
32
84
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
85
|
+
this.analysisTimer = setInterval(this.analyzeSignals, this.ANALYSIS_INTERVAL_MS);
|
|
86
|
+
this.options.onInit?.();
|
|
36
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Cleanup listeners & timers
|
|
90
|
+
*/
|
|
37
91
|
destroy() {
|
|
92
|
+
if (typeof window === 'undefined')
|
|
93
|
+
return;
|
|
94
|
+
if (!this.initialized)
|
|
95
|
+
return;
|
|
38
96
|
window.removeEventListener('mousemove', this.handleMouseMove);
|
|
39
97
|
window.removeEventListener('keydown', this.handleKeyDown);
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (this.emotion !== newEmotion) {
|
|
43
|
-
this.emotion = newEmotion;
|
|
44
|
-
this.listeners.forEach((listener) => listener(this.emotion));
|
|
98
|
+
if (this.analysisTimer) {
|
|
99
|
+
clearInterval(this.analysisTimer);
|
|
45
100
|
}
|
|
101
|
+
this.mouseSignals = [];
|
|
102
|
+
this.keySignals = [];
|
|
103
|
+
this.initialized = false;
|
|
46
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Emit emotion change event
|
|
107
|
+
*/
|
|
108
|
+
emitEmotion(type, confidence) {
|
|
109
|
+
if (type === this.currentEmotion)
|
|
110
|
+
return;
|
|
111
|
+
this.currentEmotion = type;
|
|
112
|
+
this.currentConfidence = confidence;
|
|
113
|
+
const payload = {
|
|
114
|
+
type,
|
|
115
|
+
confidence,
|
|
116
|
+
timestamp: Date.now(),
|
|
117
|
+
};
|
|
118
|
+
this.emotionListeners.forEach((listener) => listener(payload));
|
|
119
|
+
this.options.onEmotionDetected?.(payload);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Subscribe to emotion updates
|
|
123
|
+
* Returns unsubscribe function
|
|
124
|
+
*/
|
|
47
125
|
onEmotionChange(callback) {
|
|
48
|
-
this.
|
|
126
|
+
this.emotionListeners.push(callback);
|
|
127
|
+
return () => {
|
|
128
|
+
this.emotionListeners = this.emotionListeners.filter((l) => l !== callback);
|
|
129
|
+
};
|
|
49
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Get current emotion snapshot
|
|
133
|
+
*/
|
|
50
134
|
getCurrentEmotion() {
|
|
51
|
-
return
|
|
135
|
+
return {
|
|
136
|
+
type: this.currentEmotion,
|
|
137
|
+
confidence: this.currentConfidence,
|
|
138
|
+
timestamp: Date.now(),
|
|
139
|
+
};
|
|
52
140
|
}
|
|
53
141
|
}
|
|
54
|
-
|
|
55
|
-
|
|
142
|
+
/**
|
|
143
|
+
* Factory method (recommended usage)
|
|
144
|
+
*/
|
|
145
|
+
export function createEmpathAI(options) {
|
|
146
|
+
return new EmpathAI(options);
|
|
147
|
+
}
|
|
56
148
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|