openclaw-plugin-dg-lab 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 FengYing
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,197 @@
1
+ # openclaw-plugin-dg-lab
2
+
3
+ [English](README.md) | [中文](README_ZH.md)
4
+
5
+ An [OpenClaw](https://github.com/openclaw/openclaw) plugin for connecting and controlling **DG-Lab (Coyote) V3** e-stim devices via WebSocket.
6
+
7
+ ## ⚠️ Safety Disclaimer
8
+
9
+ **This plugin controls an electrical stimulation device. Misuse can cause physical harm.**
10
+
11
+ - **Never use near the chest, heart, head, or throat.** Follow all DG-Lab official safety guidelines.
12
+ - **Always start at the lowest intensity** and increase gradually.
13
+ - **Do not use** if you have a pacemaker, heart condition, epilepsy, or are pregnant.
14
+ - **Keep the device away from children.** This is an adult product.
15
+ - **You are solely responsible** for how you use this plugin. The author assumes no liability for injury, damage, or misuse.
16
+ - **The AI emotion engine can trigger stimulation automatically.** Understand this before enabling `/dg_emotion on`.
17
+ - **The software intensity limiter is a convenience feature, not a safety guarantee.** Always set safe hardware limits in the DG-Lab App.
18
+
19
+ **By using this plugin, you acknowledge these risks and agree to use it responsibly.**
20
+
21
+ ## Features
22
+
23
+ - **Native integration** — runs in-process with the OpenClaw Gateway, no external services needed
24
+ - **QR code pairing** — `/dg_qr` generates a scannable QR code for the DG-Lab App to connect
25
+ - **AI agent tools** — `dg_shock` and `dg_pulse_list` let the AI directly control stimulation
26
+ - **Emotion engine** — `/dg_emotion on` enables automatic stimulation based on keyword analysis of AI replies
27
+ - **Intensity limiter** — `/dg_limit` sets a soft cap; also respects device-side hardware limits from the App
28
+ - **Safety timer** — auto-shutdown after 1 hour continuous use, 10-minute forced rest
29
+ - **Device feedback sync** — real-time strength and limit tracking from the App
30
+ - **WebSocket heartbeat** — keeps connections alive
31
+ - **Waveform continuity** — long waveforms (>7s) are automatically chunked and sent seamlessly
32
+ - **Custom waveform library** — import `.pulses` / `.json5` / `.json` files, compatible with Coyote-Game-Hub format
33
+ - **V3 protocol compliant** — uses official frequency compression algorithm and message length limits
34
+
35
+ ## Requirements
36
+
37
+ - [OpenClaw](https://github.com/openclaw/openclaw) (2026.1+)
38
+ - A DG-Lab Coyote V3 device with the official app
39
+ - A server with a public IP (or port-forwarded) for WebSocket connections
40
+
41
+ ## Installation
42
+
43
+ ```bash
44
+ # Clone into your plugins directory
45
+ cd ~/.openclaw/workspace/plugins
46
+ git clone https://github.com/FengYing1314/openclaw-plugin-dg-lab.git
47
+ cd openclaw-plugin-dg-lab
48
+ npm install
49
+ npm run build
50
+
51
+ # Link-install the plugin
52
+ cd ~/.openclaw/workspace
53
+ openclaw plugins install -l ./plugins/openclaw-plugin-dg-lab
54
+ ```
55
+
56
+ ## Configuration
57
+
58
+ Add plugin config to `~/.openclaw/openclaw.json`:
59
+
60
+ ```json
61
+ {
62
+ "plugins": {
63
+ "entries": {
64
+ "openclaw-plugin-dg-lab": {
65
+ "enabled": true,
66
+ "config": {
67
+ "serverIp": "YOUR_PUBLIC_IP",
68
+ "port": 18888,
69
+ "limitIntensity": 40
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ | Key | Type | Default | Description |
78
+ |-----|------|---------|-------------|
79
+ | `serverIp` | string | `127.0.0.1` | Public IP or domain for QR code generation |
80
+ | `port` | number | `18888` | WebSocket server port |
81
+ | `limitIntensity` | number | `40` | Default intensity soft limit (0-200) |
82
+
83
+ **Important:** Open TCP port `18888` in your server's firewall!
84
+
85
+ Then restart:
86
+
87
+ ```bash
88
+ openclaw gateway restart
89
+ ```
90
+
91
+ ## Chat Commands
92
+
93
+ | Command | Description |
94
+ |---------|-------------|
95
+ | `/dg_qr` | Generate a QR code for the DG-Lab App to scan and connect |
96
+ | `/dg_emotion on/off` | Enable/disable emotion-driven stimulation mode |
97
+ | `/dg_limit <0-200>` | Set the intensity soft limit |
98
+ | `/dg_test +5` | Manually test a strength adjustment |
99
+ | `/dg_status` | Show current plugin state (connections, strength, device limits, queues) |
100
+ | `/dg_pulse list` | List all loaded waveform presets |
101
+ | `/dg_pulse load <file>` | Import a `.pulses` / `.json5` / `.json` waveform file |
102
+ | `/dg_pulse play <name>` | Play a custom waveform preset on channel A |
103
+ | `/dg_pulse delete <id>` | Remove a waveform from the library |
104
+
105
+ ## AI Agent Tools
106
+
107
+ ### `dg_shock`
108
+
109
+ Send stimulation to the connected device.
110
+
111
+ | Parameter | Type | Required | Description |
112
+ |-----------|------|----------|-------------|
113
+ | `strength` | number | ✓ | Intensity delta (+increase, -decrease, 0=reset) |
114
+ | `duration` | number | | Waveform duration in ms (default: 1000) |
115
+ | `waveform` | string | | `punish` / `tease` / `test` or custom preset name (default: punish) |
116
+ | `channel` | string | | `A` / `B` (default: A) |
117
+
118
+ ### `dg_pulse_list`
119
+
120
+ List all available waveform presets (built-in + custom).
121
+
122
+ ### `dg_qr_generate`
123
+
124
+ Generate a pairing QR code and return the file path.
125
+
126
+ ## Built-in Waveforms
127
+
128
+ | Name | Frequency | Intensity | Description |
129
+ |------|-----------|-----------|-------------|
130
+ | `punish` | ~66Hz (15ms) | 100% constant | High frequency sustained stimulation |
131
+ | `tease` | ~5Hz (200ms) | 20-80% sine wave | Low frequency breathing pattern |
132
+ | `test` | ~10Hz (100ms) | 50→90→50% ramp | Medium frequency short test |
133
+
134
+ ## Custom Waveforms (Pulse Library)
135
+
136
+ Place `.pulses`, `.json5`, or `.json` files in the `data/` directory. They are auto-loaded on startup.
137
+
138
+ **Supported formats:**
139
+
140
+ 1. **Coyote-Game-Hub format** (array of presets):
141
+ ```json5
142
+ [
143
+ { id: 'abc123', name: 'Breathing', pulseData: ['0A0A0A0A00000000', ...] }
144
+ ]
145
+ ```
146
+
147
+ 2. **Single preset**: `{ name: "My Wave", pulseData: [...] }`
148
+
149
+ 3. **Raw hex array**: `["0A0A0A0A64646464", ...]`
150
+
151
+ Each hex string is 16 characters (8 bytes): 4 frequency bytes (compressed, 10-240) + 4 intensity bytes (0-100). Each entry represents 100ms (4 × 25ms windows).
152
+
153
+ ## Emotion Engine
154
+
155
+ When enabled via `/dg_emotion on`, the plugin analyzes AI reply text for keywords:
156
+
157
+ | Type | Keywords (examples) | Delta | Waveform |
158
+ |------|-------------------|-------|----------|
159
+ | Punishing | 罚, 教训, 电击, punish, maximum | +15 | punish (3s) |
160
+ | Angry | 生气, 哼, 不听话, angry, warning | +8 | punish (2s) |
161
+ | Teasing | 乖, 奖励, 摸摸, good girl, reward | -3 | tease (5s) |
162
+
163
+ ## Architecture
164
+
165
+ ```
166
+ DG-Lab App ←── WebSocket ──→ Plugin WS Server ←── OpenClaw Gateway
167
+
168
+ AI agent calls dg_shock
169
+ or emotion engine hook
170
+ ```
171
+
172
+ 1. Plugin starts a WebSocket server on the configured port
173
+ 2. `/dg_qr` generates a QR code with `https://www.dungeon-lab.com/app-download.php#DGLAB-SOCKET#ws://IP:PORT/CONTROL_ID`
174
+ 3. DG-Lab App scans the QR code and connects
175
+ 4. Plugin sends strength (`strength-CH+MODE+VALUE`) and waveform (`pulse-CH:[hex...]`) commands
176
+ 5. App reports back real-time strength and limits (`strength-A+B+limitA+limitB`)
177
+
178
+ ## Safety Mechanisms
179
+
180
+ | Mechanism | Description |
181
+ |-----------|-------------|
182
+ | **Software intensity limit** | All strength changes clamped to `min(pluginLimit, deviceLimit)` |
183
+ | **Device limit sync** | Respects hardware limits set in the DG-Lab App |
184
+ | **1-hour auto-rest** | Emotion mode forces 10-minute cooldown after 60 minutes |
185
+ | **Graceful shutdown** | All channels reset to 0 on plugin stop |
186
+ | **Message length check** | Commands exceeding 1950 chars (protocol limit) are dropped |
187
+ | **Max 7s per chunk** | Waveforms auto-split into ≤70 frames per send |
188
+ | **Heartbeat** | 20s WebSocket keepalive |
189
+ | **Disconnect cleanup** | Intensity tracking resets on device disconnect |
190
+
191
+ ## Protocol Reference
192
+
193
+ This plugin implements the [DG-Lab V3 Socket Control Protocol](https://github.com/DG-LAB-OPENSOURCE/DG-LAB-OPENSOURCE/blob/main/socket/README.md) and uses the [V3 frequency compression algorithm](https://github.com/DG-LAB-OPENSOURCE/DG-LAB-OPENSOURCE/blob/main/coyote/extra/README.md).
194
+
195
+ ## License
196
+
197
+ MIT © [FengYing](https://github.com/FengYing1314)
package/README_ZH.md ADDED
@@ -0,0 +1,197 @@
1
+ # openclaw-plugin-dg-lab
2
+
3
+ [English](README.md) | [中文](README_ZH.md)
4
+
5
+ 一个 [OpenClaw](https://github.com/openclaw/openclaw) 插件,用于通过 WebSocket 连接并控制 **郊狼 (DG-Lab) V3** 电刺激设备。
6
+
7
+ ## ⚠️ 安全声明
8
+
9
+ **本插件控制电刺激设备,不当使用可能造成身体伤害。**
10
+
11
+ - **严禁在胸部、心脏、头部、颈部附近使用。** 请遵守 DG-Lab 官方安全指南。
12
+ - **务必从最低强度开始**,逐步增加。
13
+ - 如果您有心脏起搏器、心脏病、癫痫或正在怀孕,**请勿使用**。
14
+ - **请将设备远离儿童。** 这是成人用品。
15
+ - **您对使用本插件的方式承担全部责任。** 作者不对任何伤害、损坏或不当使用承担责任。
16
+ - **AI 情感引擎可以自动触发电刺激。** 在启用 `/dg_emotion on` 之前请充分了解这一点。
17
+ - **软件强度限制是便利功能,不是安全保障。** 请务必在 DG-Lab App 中设置安全的硬件上限。
18
+
19
+ **使用本插件即表示您知晓这些风险并同意负责任地使用。**
20
+
21
+ ## 功能特性
22
+
23
+ - **原生集成** — 与 OpenClaw Gateway 共享进程,无需额外服务
24
+ - **二维码配对** — `/dg_qr` 生成二维码,DG-Lab App 扫码即连
25
+ - **AI 工具调用** — `dg_shock` 和 `dg_pulse_list` 让 AI 直接控制电刺激
26
+ - **情感引擎** — `/dg_emotion on` 开启后,AI 根据回复关键词自动触发刺激
27
+ - **强度限制** — `/dg_limit` 设置软上限;同时尊重 App 端设置的硬件上限
28
+ - **安全计时** — 连续使用 1 小时自动断电,强制休息 10 分钟
29
+ - **设备反馈同步** — 实时追踪 App 上报的设备强度和上限
30
+ - **WebSocket 心跳** — 保持连接存活
31
+ - **波形连续发送** — 超过 7 秒的波形自动分段无缝发送
32
+ - **自定义波形库** — 导入 `.pulses` / `.json5` / `.json` 文件,兼容 Coyote-Game-Hub 格式
33
+ - **V3 协议合规** — 使用官方频率压缩算法和消息长度限制
34
+
35
+ ## 环境要求
36
+
37
+ - [OpenClaw](https://github.com/openclaw/openclaw) (2026.1+)
38
+ - 郊狼 Coyote V3 设备 + 官方 App
39
+ - 有公网 IP 的服务器(或端口转发)
40
+
41
+ ## 安装
42
+
43
+ ```bash
44
+ # 克隆到插件目录
45
+ cd ~/.openclaw/workspace/plugins
46
+ git clone https://github.com/FengYing1314/openclaw-plugin-dg-lab.git
47
+ cd openclaw-plugin-dg-lab
48
+ npm install
49
+ npm run build
50
+
51
+ # 链接安装插件
52
+ cd ~/.openclaw/workspace
53
+ openclaw plugins install -l ./plugins/openclaw-plugin-dg-lab
54
+ ```
55
+
56
+ ## 配置
57
+
58
+ 在 `~/.openclaw/openclaw.json` 中添加:
59
+
60
+ ```json
61
+ {
62
+ "plugins": {
63
+ "entries": {
64
+ "openclaw-plugin-dg-lab": {
65
+ "enabled": true,
66
+ "config": {
67
+ "serverIp": "你的公网IP",
68
+ "port": 18888,
69
+ "limitIntensity": 40
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ | 配置项 | 类型 | 默认值 | 说明 |
78
+ |--------|------|--------|------|
79
+ | `serverIp` | string | `127.0.0.1` | 公网 IP 或域名,用于生成二维码 |
80
+ | `port` | number | `18888` | WebSocket 服务器端口 |
81
+ | `limitIntensity` | number | `40` | 默认强度软上限 (0-200) |
82
+
83
+ **注意:请在防火墙中放行 TCP 18888 端口!**
84
+
85
+ 然后重启:
86
+
87
+ ```bash
88
+ openclaw gateway restart
89
+ ```
90
+
91
+ ## 聊天指令
92
+
93
+ | 指令 | 说明 |
94
+ |------|------|
95
+ | `/dg_qr` | 生成连接二维码,用 App 扫码连接 |
96
+ | `/dg_emotion on/off` | 开启/关闭情感联动模式 |
97
+ | `/dg_limit <0-200>` | 设置强度软上限 |
98
+ | `/dg_test +5` | 手动测试强度调整 |
99
+ | `/dg_status` | 查看当前插件状态(连接数、强度、设备上限、队列) |
100
+ | `/dg_pulse list` | 列出所有已加载的波形 |
101
+ | `/dg_pulse load <文件>` | 导入 `.pulses` / `.json5` / `.json` 波形文件 |
102
+ | `/dg_pulse play <名称>` | 在 A 通道播放自定义波形 |
103
+ | `/dg_pulse delete <id>` | 删除波形 |
104
+
105
+ ## AI 工具
106
+
107
+ ### `dg_shock`
108
+
109
+ 向连接的设备发送电刺激。
110
+
111
+ | 参数 | 类型 | 必填 | 说明 |
112
+ |------|------|------|------|
113
+ | `strength` | number | ✓ | 强度增量 (正=增加, 负=减少, 0=归零) |
114
+ | `duration` | number | | 波形持续时间 ms (默认: 1000) |
115
+ | `waveform` | string | | `punish` / `tease` / `test` 或自定义波形名称 (默认: punish) |
116
+ | `channel` | string | | `A` / `B` (默认: A) |
117
+
118
+ ### `dg_pulse_list`
119
+
120
+ 列出所有可用波形(内置 + 自定义)。
121
+
122
+ ### `dg_qr_generate`
123
+
124
+ 生成配对二维码并返回文件路径。
125
+
126
+ ## 内置波形
127
+
128
+ | 名称 | 频率 | 强度 | 描述 |
129
+ |------|------|------|------|
130
+ | `punish` | ~66Hz (15ms) | 100% 持续 | 高频持续刺激 |
131
+ | `tease` | ~5Hz (200ms) | 20-80% 正弦 | 低频呼吸式 |
132
+ | `test` | ~10Hz (100ms) | 50→90→50% | 中频短促测试 |
133
+
134
+ ## 自定义波形(波形库)
135
+
136
+ 将 `.pulses`、`.json5` 或 `.json` 文件放入插件的 `data/` 目录,启动时自动加载。
137
+
138
+ **支持的格式:**
139
+
140
+ 1. **Coyote-Game-Hub 格式**(波形数组):
141
+ ```json5
142
+ [
143
+ { id: 'abc123', name: '呼吸', pulseData: ['0A0A0A0A00000000', ...] }
144
+ ]
145
+ ```
146
+
147
+ 2. **单个波形**: `{ name: "我的波形", pulseData: [...] }`
148
+
149
+ 3. **纯 hex 数组**: `["0A0A0A0A64646464", ...]`
150
+
151
+ 每个 hex 字符串 16 字符(8 字节):4 字节频率(压缩值, 10-240)+ 4 字节强度(0-100)。每条代表 100ms(4 × 25ms 窗口)。
152
+
153
+ ## 情感引擎
154
+
155
+ 通过 `/dg_emotion on` 启用后,插件分析 AI 回复中的关键词:
156
+
157
+ | 类型 | 关键词(示例) | 增量 | 波形 |
158
+ |------|---------------|------|------|
159
+ | 惩罚 | 罚、教训、电击、punish、maximum | +15 | punish (3s) |
160
+ | 生气 | 生气、哼、不听话、angry、warning | +8 | punish (2s) |
161
+ | 安抚 | 乖、奖励、摸摸、good girl、reward | -3 | tease (5s) |
162
+
163
+ ## 架构
164
+
165
+ ```
166
+ DG-Lab App ←── WebSocket ──→ 插件 WS 服务器 ←── OpenClaw Gateway
167
+
168
+ AI 调用 dg_shock
169
+ 或情感引擎 Hook
170
+ ```
171
+
172
+ 1. 插件在配置端口启动 WebSocket 服务器
173
+ 2. `/dg_qr` 生成二维码:`https://www.dungeon-lab.com/app-download.php#DGLAB-SOCKET#ws://IP:PORT/CONTROL_ID`
174
+ 3. DG-Lab App 扫码后通过 WebSocket 连接
175
+ 4. 插件发送强度指令 (`strength-CH+MODE+VALUE`) 和波形指令 (`pulse-CH:[hex...]`)
176
+ 5. App 实时上报设备强度和上限 (`strength-A+B+limitA+limitB`)
177
+
178
+ ## 安全机制
179
+
180
+ | 机制 | 说明 |
181
+ |------|------|
182
+ | **软件强度限制** | 所有强度变化钳制到 `min(插件上限, 设备上限)` |
183
+ | **设备上限同步** | 尊重 DG-Lab App 中设置的硬件上限 |
184
+ | **1小时自动休息** | 情感模式运行 60 分钟后强制冷却 10 分钟 |
185
+ | **优雅关闭** | 插件停止时所有通道归零 |
186
+ | **消息长度检查** | 超过 1950 字符(协议限制)的指令被丢弃 |
187
+ | **最大 7 秒/段** | 波形自动拆分为 ≤70 帧/次发送 |
188
+ | **心跳包** | 20 秒 WebSocket 保活 |
189
+ | **断连清理** | 设备断开时重置强度追踪 |
190
+
191
+ ## 协议参考
192
+
193
+ 本插件实现了 [DG-Lab V3 Socket 控制协议](https://github.com/DG-LAB-OPENSOURCE/DG-LAB-OPENSOURCE/blob/main/socket/README.md),并使用了 [V3 频率压缩算法](https://github.com/DG-LAB-OPENSOURCE/DG-LAB-OPENSOURCE/blob/main/coyote/extra/README.md)。
194
+
195
+ ## 许可证
196
+
197
+ MIT © [FengYing](https://github.com/FengYing1314)
@@ -0,0 +1,85 @@
1
+ // 示例波形文件 — 来自 Coyote-Game-Hub 内置波形
2
+ // 将 .pulses / .json5 / .json 文件放入此目录,插件启动时自动加载
3
+ [
4
+ {
5
+ id: 'd6f83af0',
6
+ name: '呼吸',
7
+ pulseData: [
8
+ '0A0A0A0A00000000',
9
+ '0A0A0A0A14141414',
10
+ '0A0A0A0A28282828',
11
+ '0A0A0A0A3C3C3C3C',
12
+ '0A0A0A0A50505050',
13
+ '0A0A0A0A64646464',
14
+ '0A0A0A0A64646464',
15
+ '0A0A0A0A64646464',
16
+ '0A0A0A0A00000000',
17
+ '0A0A0A0A00000000',
18
+ '0A0A0A0A00000000',
19
+ '0A0A0A0A00000000',
20
+ ],
21
+ },
22
+ {
23
+ id: '7eae1e5f',
24
+ name: '潮汐',
25
+ pulseData: [
26
+ '0A0A0A0A00000000',
27
+ '0D0D0D0D0F0F0F0F',
28
+ '101010101E1E1E1E',
29
+ '1313131332323232',
30
+ '1616161641414141',
31
+ '1A1A1A1A50505050',
32
+ '1D1D1D1D64646464',
33
+ '202020205A5A5A5A',
34
+ '2323232350505050',
35
+ '262626264B4B4B4B',
36
+ '2A2A2A2A41414141',
37
+ '0A0A0A0A00000000',
38
+ ],
39
+ },
40
+ {
41
+ id: 'cd9868d3',
42
+ name: '心跳节奏',
43
+ pulseData: [
44
+ '7070707064646464',
45
+ '7070707064646464',
46
+ '0A0A0A0A00000000',
47
+ '0A0A0A0A00000000',
48
+ '0A0A0A0A00000000',
49
+ '0A0A0A0A00000000',
50
+ '0A0A0A0A00000000',
51
+ '0A0A0A0A46464646',
52
+ '0A0A0A0A50505050',
53
+ '0A0A0A0A5A5A5A5A',
54
+ '0A0A0A0A64646464',
55
+ '0A0A0A0A00000000',
56
+ '0A0A0A0A00000000',
57
+ '0A0A0A0A00000000',
58
+ '0A0A0A0A00000000',
59
+ '0A0A0A0A00000000',
60
+ '0A0A0A0A00000000',
61
+ ],
62
+ },
63
+ {
64
+ id: 'eea0e4ce',
65
+ name: '连击',
66
+ pulseData: [
67
+ '0A0A0A0A64646464',
68
+ '0A0A0A0A00000000',
69
+ '0A0A0A0A64646464',
70
+ '0A0A0A0A41414141',
71
+ '0A0A0A0A1E1E1E1E',
72
+ '0A0A0A0A00000000',
73
+ '0A0A0A0A00000000',
74
+ '0A0A0A0A00000000',
75
+ '0A0A0A0A64646464',
76
+ '0A0A0A0A00000000',
77
+ '0A0A0A0A64646464',
78
+ '0A0A0A0A41414141',
79
+ '0A0A0A0A1E1E1E1E',
80
+ '0A0A0A0A00000000',
81
+ '0A0A0A0A00000000',
82
+ '0A0A0A0A00000000',
83
+ ],
84
+ },
85
+ ]
@@ -0,0 +1,9 @@
1
+ export interface EmotionDelta {
2
+ type: 'neutral' | 'angry' | 'teasing' | 'punishing';
3
+ deltaValue: number;
4
+ }
5
+ export declare class EmotionEngine {
6
+ static analyze(assistantReplyText: string): EmotionDelta;
7
+ static generateWaveformForEmotion(score: EmotionDelta): string[] | null;
8
+ }
9
+ //# sourceMappingURL=emotion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emotion.d.ts","sourceRoot":"","sources":["../src/emotion.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,CAAC;IACpD,UAAU,EAAE,MAAM,CAAC;CACpB;AAqCD,qBAAa,aAAa;IACxB,MAAM,CAAC,OAAO,CAAC,kBAAkB,EAAE,MAAM,GAAG,YAAY;IASxD,MAAM,CAAC,0BAA0B,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,EAAE,GAAG,IAAI;CAQxE"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EmotionEngine = void 0;
4
+ /**
5
+ * M向动态情感分析引擎:输出相对增量 (Delta)
6
+ * 支持中英文关键词,分层匹配,优先取最高强度命中
7
+ */
8
+ const waveforms_1 = require("./waveforms");
9
+ // 从强到弱排列,优先匹配最强的
10
+ const RULES = [
11
+ {
12
+ type: 'punishing',
13
+ delta: +15,
14
+ patterns: [
15
+ /罚你/, /教训/, /电击/, /最大/, /满功率/, /跪.*下/,
16
+ /punish/i, /maximum/i, /full.?power/i,
17
+ ],
18
+ },
19
+ {
20
+ type: 'angry',
21
+ delta: +8,
22
+ patterns: [
23
+ /生气/, /哼+/, /不听话/, /不乖/, /找打/, /再犯/, /警告/, /不许/,
24
+ /angry/i, /warning/i, /disobey/i,
25
+ ],
26
+ },
27
+ {
28
+ type: 'teasing',
29
+ delta: -3,
30
+ patterns: [
31
+ /乖/, /奖励/, /轻一点/, /舒服/, /安慰/, /摸摸/, /抱抱/, /亲亲/,
32
+ /喜欢你/, /做得好/, /真棒/, /放松/,
33
+ /good\s*(girl|boy)/i, /reward/i, /relax/i, /gentle/i, /well\s*done/i,
34
+ ],
35
+ },
36
+ ];
37
+ class EmotionEngine {
38
+ static analyze(assistantReplyText) {
39
+ for (const rule of RULES) {
40
+ if (rule.patterns.some(r => r.test(assistantReplyText))) {
41
+ return { type: rule.type, deltaValue: rule.delta };
42
+ }
43
+ }
44
+ return { type: 'neutral', deltaValue: 0 };
45
+ }
46
+ static generateWaveformForEmotion(score) {
47
+ switch (score.type) {
48
+ case 'punishing': return (0, waveforms_1.punishWave)(3000);
49
+ case 'angry': return (0, waveforms_1.punishWave)(2000);
50
+ case 'teasing': return (0, waveforms_1.teaseWave)(5000);
51
+ default: return null;
52
+ }
53
+ }
54
+ }
55
+ exports.EmotionEngine = EmotionEngine;
56
+ //# sourceMappingURL=emotion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emotion.js","sourceRoot":"","sources":["../src/emotion.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,2CAAoD;AAapD,iBAAiB;AACjB,MAAM,KAAK,GAAkB;IAC3B;QACE,IAAI,EAAE,WAAW;QACjB,KAAK,EAAE,CAAC,EAAE;QACV,QAAQ,EAAE;YACR,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM;YACrC,SAAS,EAAE,UAAU,EAAE,cAAc;SACtC;KACF;IACD;QACE,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,CAAC,CAAC;QACT,QAAQ,EAAE;YACR,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;YAC/C,QAAQ,EAAE,UAAU,EAAE,UAAU;SACjC;KACF;IACD;QACE,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,CAAC,CAAC;QACT,QAAQ,EAAE;YACR,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;YAC9C,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI;YACxB,oBAAoB,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc;SACrE;KACF;CACF,CAAC;AAEF,MAAa,aAAa;IACxB,MAAM,CAAC,OAAO,CAAC,kBAA0B;QACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC;gBACxD,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;YACrD,CAAC;QACH,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,CAAC,0BAA0B,CAAC,KAAmB;QACnD,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,WAAW,CAAC,CAAC,OAAO,IAAA,sBAAU,EAAC,IAAI,CAAC,CAAC;YAC1C,KAAK,OAAO,CAAC,CAAK,OAAO,IAAA,sBAAU,EAAC,IAAI,CAAC,CAAC;YAC1C,KAAK,SAAS,CAAC,CAAG,OAAO,IAAA,qBAAS,EAAC,IAAI,CAAC,CAAC;YACzC,OAAO,CAAC,CAAU,OAAO,IAAI,CAAC;QAChC,CAAC;IACH,CAAC;CACF;AAlBD,sCAkBC"}
@@ -0,0 +1,2 @@
1
+ export default function registerPlugin(api: any): void;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA6JA,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,GAAG,EAAE,GAAG,QA+U9C"}