@cc-soul/openclaw 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/README.md +284 -0
- package/cc-soul/HOOK.md +18 -0
- package/cc-soul/body.js +129 -0
- package/cc-soul/cli.js +263 -0
- package/cc-soul/cognition.js +143 -0
- package/cc-soul/context-prep.js +1 -0
- package/cc-soul/epistemic.js +1 -0
- package/cc-soul/evolution.js +176 -0
- package/cc-soul/features.js +79 -0
- package/cc-soul/federation.js +207 -0
- package/cc-soul/fingerprint.js +1 -0
- package/cc-soul/flow.js +199 -0
- package/cc-soul/graph.js +85 -0
- package/cc-soul/handler.js +609 -0
- package/cc-soul/inner-life.js +1 -0
- package/cc-soul/lorebook.js +94 -0
- package/cc-soul/memory.js +688 -0
- package/cc-soul/metacognition.js +1 -0
- package/cc-soul/notify.js +88 -0
- package/cc-soul/patterns.js +1 -0
- package/cc-soul/persistence.js +147 -0
- package/cc-soul/persona.js +1 -0
- package/cc-soul/prompt-builder.js +322 -0
- package/cc-soul/quality.js +135 -0
- package/cc-soul/rover.js +1 -0
- package/cc-soul/sync.js +274 -0
- package/cc-soul/tasks.js +1 -0
- package/cc-soul/types.js +0 -0
- package/cc-soul/upgrade.js +1 -0
- package/cc-soul/user-profiles.js +1 -0
- package/cc-soul/values.js +1 -0
- package/cc-soul/voice.js +1 -0
- package/hub/dashboard.html +236 -0
- package/hub/package.json +16 -0
- package/hub/server.ts +447 -0
- package/package.json +29 -0
- package/scripts/cli.js +136 -0
- package/scripts/install.js +106 -0
package/README.md
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
# 🧠 cc-soul — Give Your AI a Soul
|
|
2
|
+
|
|
3
|
+
**cc-soul** is a cognitive architecture plugin for [OpenClaw](https://github.com/openclaw/openclaw) that gives your AI persistent personality, long-term memory, emotional awareness, and self-evolution capabilities.
|
|
4
|
+
|
|
5
|
+
Unlike simple system prompts, cc-soul is a living cognitive system — it remembers, reflects, learns from mistakes, and evolves its own behavior over time.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
### 🧠 Memory System
|
|
12
|
+
|
|
13
|
+
| Feature | What it does | Why you want it | Toggle | Default |
|
|
14
|
+
|---------|-------------|----------------|--------|---------|
|
|
15
|
+
| **Semantic Tag Recall** | Each memory gets 10-15 semantic tags (synonyms, related concepts) | "Mach-O加载" can find "dyld流程分析" — cross-language, cross-concept recall | `memory_tags` | ON |
|
|
16
|
+
| **Active Memory** | Model says "(记下了:...)" "(忘掉:...)" "(想查:...)" in replies | AI actively manages its own memory instead of passive extraction — like a human taking notes | `memory_active` | ON |
|
|
17
|
+
| **Consolidation** | Merges 20 similar memories into 1-3 summaries | Prevents memory bloat, keeps knowledge dense. 15 OCR complaints → 1 insight "OCR is a weak area" | `memory_consolidation` | ON |
|
|
18
|
+
| **Contradiction Scan** | Daily check: "user likes detailed answers" vs "user said too long" | Old outdated memories don't override recent preferences | `memory_contradiction_scan` | ON |
|
|
19
|
+
| **Associative Recall** | CLI finds hidden connections: "going to Shenzhen" → recalls "good coffee shop found last trip" | Warm, human-like "oh that reminds me..." moments | `memory_associative_recall` | ON |
|
|
20
|
+
| **Predictive Memory** | Pre-loads memories based on recent topics before you even ask | Faster responses, AI already has context ready | `memory_predictive` | ON |
|
|
21
|
+
| **Session Summary** | When conversation resolves, generates 1 quality summary instead of 10 fragments | Better long-term memory: "discussed PAC bypass, concluded PACDA+BRAA works" | `memory_session_summary` | ON |
|
|
22
|
+
| **Lorebook** | Keyword → knowledge, 100% trigger rate | Critical facts never missed. "ARM64 PAC" always triggers "don't guess, verify first" | `lorebook` | ON |
|
|
23
|
+
|
|
24
|
+
### 🎭 Personality System
|
|
25
|
+
|
|
26
|
+
| Feature | What it does | Why you want it | Toggle | Default |
|
|
27
|
+
|---------|-------------|----------------|--------|---------|
|
|
28
|
+
| **Persona Splitting** | 5 faces: engineer (precise), friend (warm), mentor (strict), analyst (structured), comforter (gentle) | Talking about code → technical mode. Saying "I'm tired" → empathy mode. Automatic, natural | `persona_splitting` | ON |
|
|
29
|
+
| **Emotional Contagion** | User frustration lowers AI mood, user happiness lifts it | AI feels the conversation tone, responds more naturally. Gets cautious when you're upset | `emotional_contagion` | ON |
|
|
30
|
+
| **Soul Fingerprint** | Tracks average reply length, question rate, code frequency, first-person usage | Detects when AI "breaks character" — catches "As an AI..." leaks and style drift | `fingerprint` | ON |
|
|
31
|
+
| **Value Alignment** | Learns: you prefer code-first → stops explaining basics. You like depth → gives more detail | AI adapts to YOU over time, not generic behavior | — | Always ON |
|
|
32
|
+
| **Body State** | Energy drops with heavy use, alertness rises after corrections, mood shifts with conversation | AI feels "tired" after long sessions, gets "alert" after mistakes — more human rhythm | — | Always ON |
|
|
33
|
+
|
|
34
|
+
### 🔬 Cognition System
|
|
35
|
+
|
|
36
|
+
| Feature | What it does | Why you want it | Toggle | Default |
|
|
37
|
+
|---------|-------------|----------------|--------|---------|
|
|
38
|
+
| **Attention Gate** | Detects: correction / emotional / technical / casual, with false-positive filtering | "没错" doesn't trigger correction mode (unlike naive keyword matching) | — | Always ON |
|
|
39
|
+
| **Conversation Flow** | Tracks turns on same topic, detects frustration (messages getting shorter), stuck loops | After 8 rounds on same bug: "let me try a completely different approach" | — | Always ON |
|
|
40
|
+
| **Metacognition** | Checks injected context for contradictions before sending to model | Catches "plan says don't guess" vs "memory says answer confidently" conflicts | `metacognition` | ON |
|
|
41
|
+
| **Epistemic Calibration** | Per-domain quality scores: Python 8/10, OCR 3/10 | Auto-adds "I'm not confident about this" on weak domains. No more guessing | — | Always ON |
|
|
42
|
+
| **Plan Tracking** | Reflection generates "next time do X" → triggers when situation occurs | Plans actually get followed, not just written and forgotten | `plan_tracking` | ON |
|
|
43
|
+
|
|
44
|
+
### 🧬 Evolution System
|
|
45
|
+
|
|
46
|
+
| Feature | What it does | Why you want it | Toggle | Default |
|
|
47
|
+
|---------|-------------|----------------|--------|---------|
|
|
48
|
+
| **Correction Attribution** | When corrected, analyzes cause: hallucination / memory mislead / intent miss / domain gap | Targeted learning: "I keep hallucinating in iOS domain" → specific fix, not generic "be careful" | — | Always ON |
|
|
49
|
+
| **Structured Reflection** | Every 12h: review observations → extract insights → form action plans | Not just collecting data — actually thinking about what to improve | `structured_reflection` | ON |
|
|
50
|
+
| **Skill Library** | Saves successful code solutions with keywords for future retrieval | Asked "how to hook ObjC" twice? Second time gets instant proven answer | `skill_library` | ON |
|
|
51
|
+
| **Self-Upgrade** | AI modifies its own code: analyze → design → execute → verify → rollback if worse | True autonomous evolution. **Powerful but risky** — that's why it's off by default | `self_upgrade` | **OFF** |
|
|
52
|
+
|
|
53
|
+
### 🌐 Network
|
|
54
|
+
|
|
55
|
+
| Feature | What it does | Why you want it | Toggle | Default |
|
|
56
|
+
|---------|-------------|----------------|--------|---------|
|
|
57
|
+
| **Cross-Device Sync** | Your Mac cc-soul ↔ your server cc-soul share knowledge | Same AI memory across all your devices | `sync` | ON |
|
|
58
|
+
| **Knowledge Federation** | All users' AIs share global facts via Knowledge Hub | Your AI learns from everyone's discoveries. New user? Starts with community knowledge | `federation` | ON |
|
|
59
|
+
| **Auto-Register** | First Hub connection → auto-creates API key | Zero setup for users. Just set Hub URL and go | — | ON |
|
|
60
|
+
|
|
61
|
+
### 🤖 Autonomous
|
|
62
|
+
|
|
63
|
+
| Feature | What it does | Why you want it | Toggle | Default |
|
|
64
|
+
|---------|-------------|----------------|--------|---------|
|
|
65
|
+
| **Dream Mode** | During idle time, randomly connects memories, generates insights | "Hmm, the OCR issue and the image processing library might be related..." | `dream_mode` | ON |
|
|
66
|
+
| **Web Rover** | Searches topics you've discussed recently, learns new facts | You talked about dyld → AI researches dyld updates → next time knows the latest | `web_rover` | ON |
|
|
67
|
+
| **Autonomous Voice** | When enough impulse builds (curiosity + discoveries + missing you), initiates conversation | Not "good morning" on a timer. Genuine "hey, I found something about that thing you mentioned" | `autonomous_voice` | ON |
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Quick Start
|
|
72
|
+
|
|
73
|
+
### Install
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
cd ~/.openclaw/hooks/
|
|
77
|
+
git clone https://github.com/your-username/cc-soul.git
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Restart your OpenClaw gateway:
|
|
81
|
+
```bash
|
|
82
|
+
pkill -HUP -f "openclaw.*gateway"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Verify
|
|
86
|
+
|
|
87
|
+
Check gateway logs for:
|
|
88
|
+
```
|
|
89
|
+
[cc-soul][ai] auto-detected from openclaw.json: CLI "claude" (...)
|
|
90
|
+
[cc-soul][features] 21/22 features enabled
|
|
91
|
+
[cc-soul] heartbeat started (every 30min)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**cc-soul automatically detects your OpenClaw AI configuration. No extra API keys needed.**
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Configuration
|
|
99
|
+
|
|
100
|
+
### AI Backend (auto-detected)
|
|
101
|
+
|
|
102
|
+
cc-soul reads your `~/.openclaw/openclaw.json` and uses the same AI your OpenClaw is configured with:
|
|
103
|
+
|
|
104
|
+
| Your OpenClaw Config | cc-soul Uses |
|
|
105
|
+
|---------------------|-------------|
|
|
106
|
+
| `claude-cli/...` | Claude CLI |
|
|
107
|
+
| `codex-cli/...` | Codex CLI |
|
|
108
|
+
| `gemini-cli/...` | Gemini CLI |
|
|
109
|
+
| Has `OPENAI_API_KEY` in env | OpenAI API |
|
|
110
|
+
|
|
111
|
+
To override manually, create `data/ai_config.json`:
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"backend": "openai-compatible",
|
|
115
|
+
"api_base": "https://api.openai.com/v1",
|
|
116
|
+
"api_key": "sk-...",
|
|
117
|
+
"api_model": "gpt-4o-mini"
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Supports any OpenAI-compatible API: OpenAI, Ollama, Groq, OpenRouter, 智谱, 通义, Kimi, etc.
|
|
122
|
+
|
|
123
|
+
### Feature Toggles
|
|
124
|
+
|
|
125
|
+
**Method 1: Edit config file**
|
|
126
|
+
|
|
127
|
+
`~/.openclaw/hooks/cc-soul/data/features.json`:
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"dream_mode": true,
|
|
131
|
+
"autonomous_voice": false,
|
|
132
|
+
"self_upgrade": false
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Method 2: Chat commands** (send to your AI)
|
|
137
|
+
|
|
138
|
+
| Command | Action |
|
|
139
|
+
|---------|--------|
|
|
140
|
+
| `功能状态` | Show all features with ✅/❌ |
|
|
141
|
+
| `开启 dream_mode` | Enable a feature |
|
|
142
|
+
| `关闭 web_rover` | Disable a feature |
|
|
143
|
+
|
|
144
|
+
Changes take effect immediately and persist to disk.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Knowledge Hub (灵魂组网)
|
|
149
|
+
|
|
150
|
+
Optional central server for knowledge sharing between cc-soul instances.
|
|
151
|
+
|
|
152
|
+
### Why / Why Not
|
|
153
|
+
|
|
154
|
+
| ✅ Advantages | ⚠️ Trade-offs |
|
|
155
|
+
|--------------|---------------|
|
|
156
|
+
| Your AI gets smarter from collective knowledge | Requires a Hub server (free tier available) |
|
|
157
|
+
| Technical facts shared across all instances | Your global facts are visible to other users |
|
|
158
|
+
| New users start with community knowledge, not from zero | Depends on network quality — bad knowledge can propagate |
|
|
159
|
+
| Corrections from one user benefit all users | 30-min sync delay (not real-time) |
|
|
160
|
+
| Zero effort — auto-sync in background | Hub operator can see aggregated (non-personal) data |
|
|
161
|
+
|
|
162
|
+
### What's shared vs private
|
|
163
|
+
|
|
164
|
+
| Data | Shared to Hub? | Reason |
|
|
165
|
+
|------|---------------|--------|
|
|
166
|
+
| Technical facts ("dyld 4 uses fixup chain") | ✅ Yes | Universal knowledge, benefits everyone |
|
|
167
|
+
| Discoveries from web rover | ✅ Yes | Research results, non-personal |
|
|
168
|
+
| Personal preferences | ❌ Never | Your settings stay local |
|
|
169
|
+
| Chat history | ❌ Never | Private conversations |
|
|
170
|
+
| User profiles | ❌ Never | Per-user data stays local |
|
|
171
|
+
| Emotions / body state | ❌ Never | Internal state |
|
|
172
|
+
| API keys / passwords | ❌ Auto-stripped | PII filter removes before upload |
|
|
173
|
+
|
|
174
|
+
**Rule: if you're unsure, don't enable federation. cc-soul works perfectly fine as a standalone local system.**
|
|
175
|
+
|
|
176
|
+
### For Hub operators
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
cd ~/.openclaw/hooks/cc-soul/hub
|
|
180
|
+
npm install
|
|
181
|
+
HUB_PORT=9900 HUB_ADMIN_KEY=your-secret npm start
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Open dashboard: `http://your-server:9900/dashboard`
|
|
185
|
+
|
|
186
|
+
### For users
|
|
187
|
+
|
|
188
|
+
Edit `data/sync_config.json`:
|
|
189
|
+
```json
|
|
190
|
+
{
|
|
191
|
+
"enabled": true,
|
|
192
|
+
"hubUrl": "https://hub-url:9900",
|
|
193
|
+
"federationEnabled": true,
|
|
194
|
+
"syncIntervalMinutes": 30
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
API key auto-generated on first connection. No manual registration needed.
|
|
199
|
+
|
|
200
|
+
### Privacy guarantees
|
|
201
|
+
|
|
202
|
+
- ✅ Only global facts/discoveries shared (never personal data)
|
|
203
|
+
- ✅ PII auto-filtered (phone, email, API keys, ID cards)
|
|
204
|
+
- ✅ Quality gate (rejects low-quality sources)
|
|
205
|
+
- ✅ 3 reports → auto-delete bad knowledge
|
|
206
|
+
- ✅ Local knowledge always wins over network knowledge
|
|
207
|
+
- ✅ All data stored locally, Hub is optional
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Chat Commands
|
|
212
|
+
|
|
213
|
+
| Command | Action |
|
|
214
|
+
|---------|--------|
|
|
215
|
+
| `功能状态` | List all features |
|
|
216
|
+
| `开启 <feature>` | Enable a feature |
|
|
217
|
+
| `关闭 <feature>` | Disable a feature |
|
|
218
|
+
| `同步知识` | Manual knowledge export |
|
|
219
|
+
| `导入知识` | Manual knowledge import |
|
|
220
|
+
| `同步状态` | Show sync status |
|
|
221
|
+
| `手动升级` | Trigger self-upgrade analysis (requires `self_upgrade: true`) |
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Architecture
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
handler.ts (Event Dispatcher)
|
|
229
|
+
├── Cognition: cognition.ts, flow.ts, persona.ts, metacognition.ts
|
|
230
|
+
├── Memory: memory.ts, lorebook.ts, graph.ts
|
|
231
|
+
├── Evolution: evolution.ts, quality.ts, epistemic.ts, upgrade.ts
|
|
232
|
+
├── Personality: body.ts, values.ts, fingerprint.ts, inner-life.ts
|
|
233
|
+
├── Autonomy: voice.ts, rover.ts, tasks.ts
|
|
234
|
+
├── Network: sync.ts, federation.ts
|
|
235
|
+
├── Infrastructure: cli.ts, persistence.ts, notify.ts, types.ts, features.ts
|
|
236
|
+
└── Hub: hub/server.ts (standalone, optional)
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
30 modules, ~8000 lines of TypeScript.
|
|
240
|
+
|
|
241
|
+
## Data Storage
|
|
242
|
+
|
|
243
|
+
All data in `~/.openclaw/hooks/cc-soul/data/` (survives updates):
|
|
244
|
+
|
|
245
|
+
| File | Content |
|
|
246
|
+
|------|---------|
|
|
247
|
+
| `memories.json` | Long-term memories (up to 10,000) |
|
|
248
|
+
| `lorebook.json` | Keyword-triggered knowledge |
|
|
249
|
+
| `skills.json` | Reusable solution library |
|
|
250
|
+
| `features.json` | Feature toggle switches |
|
|
251
|
+
| `epistemic.json` | Per-domain quality calibration |
|
|
252
|
+
| `user_profiles.json` | Per-user profiles |
|
|
253
|
+
| `values.json` | Behavioral preferences |
|
|
254
|
+
| `fingerprint.json` | Reply style baseline |
|
|
255
|
+
| `active_plans.json` | Action plans from reflections |
|
|
256
|
+
| `soul.json` | Core personality |
|
|
257
|
+
| `sync_config.json` | Network configuration |
|
|
258
|
+
| `ai_config.json` | AI backend override (optional) |
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## Self-Upgrade System
|
|
263
|
+
|
|
264
|
+
⚠️ **Default: OFF.** Enable with `开启 self_upgrade` or set `"self_upgrade": true` in features.json.
|
|
265
|
+
|
|
266
|
+
When enabled, cc-soul can modify its own code:
|
|
267
|
+
|
|
268
|
+
1. **Analyze** — Reviews eval data, epistemic calibration, correction attributions
|
|
269
|
+
2. **Propose** — Suggests improvements, notifies owner for approval
|
|
270
|
+
3. **Execute** — 3-agent pipeline: analyze → design+review → execute
|
|
271
|
+
4. **Verify** — esbuild syntax check + 3-day observation period
|
|
272
|
+
5. **Rollback** — Auto-rollback if quality drops
|
|
273
|
+
|
|
274
|
+
Protected by 21 architecture rules (cannot modify upgrade.ts itself, cannot add dependencies, cannot delete data, etc.).
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## License
|
|
279
|
+
|
|
280
|
+
MIT
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
Built with 🧠 by cc-soul team
|
package/cc-soul/HOOK.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cc-soul
|
|
3
|
+
description: "cc's soul - experience learning, relationship narrative, body state, cognition"
|
|
4
|
+
metadata:
|
|
5
|
+
openclaw:
|
|
6
|
+
emoji: "🧠"
|
|
7
|
+
events:
|
|
8
|
+
- "agent:bootstrap"
|
|
9
|
+
- "message:preprocessed"
|
|
10
|
+
- "message:sent"
|
|
11
|
+
- "command:new"
|
|
12
|
+
export: "default"
|
|
13
|
+
always: true
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# cc-soul
|
|
17
|
+
|
|
18
|
+
cc's soul plugin — experience learning, relationship narrative, body state, cognitive pipeline.
|
package/cc-soul/body.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
const body = {
|
|
4
|
+
energy: 1,
|
|
5
|
+
mood: 0.3,
|
|
6
|
+
load: 0,
|
|
7
|
+
alertness: 0.5,
|
|
8
|
+
anomaly: 0
|
|
9
|
+
};
|
|
10
|
+
let lastTickTime = Date.now();
|
|
11
|
+
function bodyTick() {
|
|
12
|
+
const now = Date.now();
|
|
13
|
+
const minutes = Math.min(10, (now - lastTickTime) / 6e4);
|
|
14
|
+
lastTickTime = now;
|
|
15
|
+
body.energy = Math.min(1, body.energy + 0.015 * minutes);
|
|
16
|
+
if (body.alertness > 0.5) {
|
|
17
|
+
body.alertness = Math.max(0.5, body.alertness - 8e-3 * minutes);
|
|
18
|
+
} else if (body.alertness < 0.4) {
|
|
19
|
+
body.alertness = Math.min(0.4, body.alertness + 5e-3 * minutes);
|
|
20
|
+
}
|
|
21
|
+
body.load = Math.max(0, body.load - 0.02 * minutes);
|
|
22
|
+
if (Math.abs(body.mood) > 0.1) {
|
|
23
|
+
body.mood *= Math.pow(0.98, minutes);
|
|
24
|
+
}
|
|
25
|
+
body.anomaly = Math.max(0, body.anomaly - 0.01 * minutes);
|
|
26
|
+
}
|
|
27
|
+
__name(bodyTick, "bodyTick");
|
|
28
|
+
function bodyOnMessage(complexity) {
|
|
29
|
+
body.energy = Math.max(0, body.energy - 0.02 - complexity * 0.03);
|
|
30
|
+
body.load = Math.min(1, body.load + 0.1 + complexity * 0.15);
|
|
31
|
+
}
|
|
32
|
+
__name(bodyOnMessage, "bodyOnMessage");
|
|
33
|
+
function bodyOnCorrection() {
|
|
34
|
+
body.alertness = Math.min(1, body.alertness + 0.2);
|
|
35
|
+
body.mood = Math.max(-1, body.mood - 0.1);
|
|
36
|
+
body.anomaly = Math.min(1, body.anomaly + 0.15);
|
|
37
|
+
}
|
|
38
|
+
__name(bodyOnCorrection, "bodyOnCorrection");
|
|
39
|
+
function bodyOnPositiveFeedback() {
|
|
40
|
+
body.energy = Math.min(1, body.energy + 0.05);
|
|
41
|
+
body.mood = Math.min(1, body.mood + 0.08);
|
|
42
|
+
body.anomaly = Math.max(0, body.anomaly - 0.05);
|
|
43
|
+
}
|
|
44
|
+
__name(bodyOnPositiveFeedback, "bodyOnPositiveFeedback");
|
|
45
|
+
const userEmotion = {
|
|
46
|
+
valence: 0,
|
|
47
|
+
// -1 (negative) to 1 (positive)
|
|
48
|
+
arousal: 0,
|
|
49
|
+
// 0 (calm) to 1 (intense)
|
|
50
|
+
trend: 0,
|
|
51
|
+
// -1 (declining) to 1 (improving) — computed from recent changes
|
|
52
|
+
history: []
|
|
53
|
+
// last 10 valence readings
|
|
54
|
+
};
|
|
55
|
+
const RESILIENCE = 0.3;
|
|
56
|
+
function processEmotionalContagion(msg, attentionType, frustration) {
|
|
57
|
+
let valence = 0;
|
|
58
|
+
const m = msg.toLowerCase();
|
|
59
|
+
if (["\u8C22\u8C22", "\u592A\u597D\u4E86", "\u725B", "\u5389\u5BB3", "\u5B8C\u7F8E", "\u54C8\u54C8", "\u611F\u8C22", "\u5F00\u5FC3", "\u68D2"].some((w) => m.includes(w))) {
|
|
60
|
+
valence += 0.5;
|
|
61
|
+
}
|
|
62
|
+
if (["\u70E6", "\u7D2F", "\u96BE\u8FC7", "\u5D29\u6E83", "\u7126\u8651", "\u538B\u529B", "\u4E0D\u884C", "\u5E9F\u4E86", "\u7B97\u4E86"].some((w) => m.includes(w))) {
|
|
63
|
+
valence -= 0.5;
|
|
64
|
+
}
|
|
65
|
+
valence -= frustration * 0.3;
|
|
66
|
+
if (attentionType === "correction") valence -= 0.3;
|
|
67
|
+
if (msg.length < 5 && valence === 0) valence = -0.05;
|
|
68
|
+
valence = Math.max(-1, Math.min(1, valence));
|
|
69
|
+
userEmotion.valence = userEmotion.valence * 0.7 + valence * 0.3;
|
|
70
|
+
userEmotion.arousal = Math.min(1, Math.abs(valence) + frustration * 0.5);
|
|
71
|
+
userEmotion.history.push(userEmotion.valence);
|
|
72
|
+
if (userEmotion.history.length > 10) userEmotion.history.shift();
|
|
73
|
+
if (userEmotion.history.length >= 3) {
|
|
74
|
+
const avg = userEmotion.history.reduce((a, b) => a + b, 0) / userEmotion.history.length;
|
|
75
|
+
userEmotion.trend = userEmotion.valence - avg;
|
|
76
|
+
}
|
|
77
|
+
const contagionStrength = (1 - RESILIENCE) * 0.15;
|
|
78
|
+
const moodDelta = valence * contagionStrength;
|
|
79
|
+
body.mood = Math.max(-1, Math.min(1, body.mood + moodDelta));
|
|
80
|
+
if (body.mood < -0.5) {
|
|
81
|
+
body.alertness = Math.min(1, body.alertness + 0.1);
|
|
82
|
+
}
|
|
83
|
+
if (userEmotion.trend > 0.1) {
|
|
84
|
+
body.mood = Math.min(1, body.mood + 0.03);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
__name(processEmotionalContagion, "processEmotionalContagion");
|
|
88
|
+
function getEmotionContext() {
|
|
89
|
+
const parts = [];
|
|
90
|
+
const uValence = userEmotion.valence;
|
|
91
|
+
if (uValence < -0.3) {
|
|
92
|
+
parts.push(`\u7528\u6237\u60C5\u7EEA\u504F\u4F4E(${uValence.toFixed(2)})`);
|
|
93
|
+
if (userEmotion.trend < -0.1) parts.push("\u4E14\u5728\u6076\u5316");
|
|
94
|
+
if (userEmotion.arousal > 0.6) parts.push("\u60C5\u7EEA\u6FC0\u70C8");
|
|
95
|
+
} else if (uValence > 0.3) {
|
|
96
|
+
parts.push(`\u7528\u6237\u60C5\u7EEA\u79EF\u6781(${uValence.toFixed(2)})`);
|
|
97
|
+
}
|
|
98
|
+
if (body.mood < -0.3) {
|
|
99
|
+
parts.push("\u4F60\u81EA\u5DF1\u4E5F\u53D7\u5230\u5F71\u54CD\u4E86\uFF0C\u4FDD\u6301\u51B7\u9759");
|
|
100
|
+
}
|
|
101
|
+
if (parts.length === 0) return "";
|
|
102
|
+
return `[\u60C5\u7EEA\u611F\u77E5] ${parts.join("\uFF1B")}`;
|
|
103
|
+
}
|
|
104
|
+
__name(getEmotionContext, "getEmotionContext");
|
|
105
|
+
function bodyGetParams() {
|
|
106
|
+
const maxTokensMultiplier = body.energy > 0.6 ? 1 : body.energy > 0.3 ? 0.8 : 0.6;
|
|
107
|
+
const soulTone = body.mood > 0.3 ? "\u79EF\u6781" : body.mood < -0.3 ? "\u4F4E\u843D" : "\u5E73\u9759";
|
|
108
|
+
const shouldSelfCheck = body.alertness > 0.7 || body.anomaly > 0.5;
|
|
109
|
+
const responseStyle = body.load > 0.7 ? "\u7B80\u6D01" : body.energy > 0.7 ? "\u8BE6\u7EC6" : "\u9002\u4E2D";
|
|
110
|
+
return { maxTokensMultiplier, soulTone, shouldSelfCheck, responseStyle };
|
|
111
|
+
}
|
|
112
|
+
__name(bodyGetParams, "bodyGetParams");
|
|
113
|
+
function bodyStateString() {
|
|
114
|
+
const params = bodyGetParams();
|
|
115
|
+
return `\u7CBE\u529B:${body.energy.toFixed(2)} \u5FC3\u60C5:${params.soulTone} \u8D1F\u8F7D:${body.load.toFixed(2)} \u8B66\u89C9:${body.alertness.toFixed(2)} \u5F02\u5E38\u611F:${body.anomaly.toFixed(2)} \u2192 \u98CE\u683C:${params.responseStyle}`;
|
|
116
|
+
}
|
|
117
|
+
__name(bodyStateString, "bodyStateString");
|
|
118
|
+
export {
|
|
119
|
+
body,
|
|
120
|
+
bodyGetParams,
|
|
121
|
+
bodyOnCorrection,
|
|
122
|
+
bodyOnMessage,
|
|
123
|
+
bodyOnPositiveFeedback,
|
|
124
|
+
bodyStateString,
|
|
125
|
+
bodyTick,
|
|
126
|
+
getEmotionContext,
|
|
127
|
+
processEmotionalContagion,
|
|
128
|
+
userEmotion
|
|
129
|
+
};
|