@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 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
@@ -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.
@@ -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
+ };