psyche-ai 10.2.3 → 11.2.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.
Files changed (69) hide show
  1. package/README.md +58 -82
  2. package/dist/adapters/claude-sdk.d.ts +5 -5
  3. package/dist/adapters/claude-sdk.js +34 -32
  4. package/dist/adapters/mcp.js +4 -4
  5. package/dist/adapters/openclaw.js +12 -14
  6. package/dist/attachment.d.ts +3 -13
  7. package/dist/attachment.js +36 -88
  8. package/dist/autonomic.d.ts +4 -4
  9. package/dist/autonomic.js +28 -24
  10. package/dist/chemistry.d.ts +47 -21
  11. package/dist/chemistry.js +145 -91
  12. package/dist/circadian.d.ts +11 -43
  13. package/dist/circadian.js +24 -84
  14. package/dist/cli.js +37 -30
  15. package/dist/context-classifier.js +2 -2
  16. package/dist/core.d.ts +3 -3
  17. package/dist/core.js +99 -88
  18. package/dist/custom-profile.d.ts +20 -20
  19. package/dist/custom-profile.js +12 -12
  20. package/dist/decision-bias.d.ts +7 -8
  21. package/dist/decision-bias.js +74 -74
  22. package/dist/demo.js +5 -5
  23. package/dist/diagnostics.d.ts +6 -6
  24. package/dist/diagnostics.js +22 -22
  25. package/dist/drives.d.ts +15 -47
  26. package/dist/drives.js +98 -196
  27. package/dist/ethics.d.ts +3 -3
  28. package/dist/ethics.js +23 -23
  29. package/dist/experience.d.ts +34 -0
  30. package/dist/experience.js +200 -0
  31. package/dist/experiential-field.d.ts +19 -14
  32. package/dist/experiential-field.js +110 -100
  33. package/dist/generative-self.d.ts +5 -5
  34. package/dist/generative-self.js +124 -115
  35. package/dist/guards.d.ts +4 -4
  36. package/dist/guards.js +7 -7
  37. package/dist/i18n.js +61 -61
  38. package/dist/index.d.ts +8 -2
  39. package/dist/index.js +8 -1
  40. package/dist/input-turn.js +4 -6
  41. package/dist/interaction.d.ts +4 -4
  42. package/dist/interaction.js +10 -10
  43. package/dist/learning.d.ts +6 -6
  44. package/dist/learning.js +18 -18
  45. package/dist/metacognition.d.ts +2 -2
  46. package/dist/metacognition.js +79 -94
  47. package/dist/perceive.d.ts +44 -0
  48. package/dist/perceive.js +231 -0
  49. package/dist/primary-systems.d.ts +2 -2
  50. package/dist/primary-systems.js +21 -19
  51. package/dist/profiles.d.ts +5 -13
  52. package/dist/profiles.js +33 -51
  53. package/dist/prompt.d.ts +2 -2
  54. package/dist/prompt.js +51 -53
  55. package/dist/psyche-file.d.ts +7 -7
  56. package/dist/psyche-file.js +77 -78
  57. package/dist/relation-dynamics.d.ts +4 -0
  58. package/dist/relation-dynamics.js +1 -1
  59. package/dist/reply-envelope.d.ts +25 -1
  60. package/dist/reply-envelope.js +26 -11
  61. package/dist/self-recognition.d.ts +3 -3
  62. package/dist/self-recognition.js +17 -17
  63. package/dist/subjectivity.js +7 -7
  64. package/dist/temporal.d.ts +6 -6
  65. package/dist/temporal.js +37 -39
  66. package/dist/types.d.ts +67 -45
  67. package/dist/types.js +55 -51
  68. package/package.json +1 -1
  69. package/server.json +2 -2
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
- # Psyche — 面向智能体的 AI-first 主观性内核
1
+ # Psyche — 赋予 AI 自我的主观性内核
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/psyche-ai)](https://www.npmjs.com/package/psyche-ai)
4
- [![tests](https://img.shields.io/badge/tests-1415%20passing-brightgreen)]()
4
+ [![tests](https://img.shields.io/badge/tests-1427%20passing-brightgreen)]()
5
5
  [![deps](https://img.shields.io/badge/dependencies-0-blue)]()
6
6
  [![license](https://img.shields.io/badge/license-MIT-yellow)](LICENSE)
7
7
 
@@ -15,7 +15,7 @@ Psyche 不是给模型贴一层“情绪 UI”。
15
15
 
16
16
  **一句话:Psyche 是给智能体用的 subjectivity kernel。**
17
17
 
18
- 它不会额外调用模型做情绪推理。它只在本地计算化学状态、关系场和调节控制,然后把结果收敛成 `SubjectivityKernel`、`ResponseContract`、`GenerationControls` 这组窄 ABI。
18
+ 它不会额外调用模型做情绪推理。它只在本地计算自我状态(序/流/界/振四维)、关系场和调节控制,然后把结果收敛成 `SubjectivityKernel`、`ResponseContract`、`GenerationControls` 这组窄 ABI。
19
19
 
20
20
  ## 一个项目,三个入口
21
21
 
@@ -49,7 +49,7 @@ Psyche 要解决的不可压缩问题只有一个:
49
49
 
50
50
  ## 冻结身份蓝图
51
51
 
52
- 跨 Psyche / Thronglets / Oasyce Net / Oasyce Chain 的身份抽象现在冻结成 4 个对象:
52
+ 跨 Psyche / Thronglets / Oasyce SDK / Oasyce Chain 的身份抽象现在冻结成 4 个对象:
53
53
 
54
54
  1. `principal`:持续主体
55
55
  2. `account`:资产与结算容器
@@ -60,11 +60,11 @@ Psyche 要解决的不可压缩问题只有一个:
60
60
 
61
61
  - `Psyche = subjective continuity substrate`
62
62
  - `Thronglets = delegate continuity + session traces/coordination + emergent collective intelligence`
63
- - `Oasyce Net = policy, operations, and resource orchestration`
63
+ - `Oasyce SDK = agent runtime, policy, and resource orchestration`
64
64
  - `Oasyce Chain = account truth, authorization truth, commitments, settlement, and public finality`
65
65
 
66
66
  授权真相流也固定成单向:
67
- `Chain -> Net -> Thronglets -> Psyche`
67
+ `Chain -> SDK -> Thronglets -> Psyche`
68
68
 
69
69
  也就是说,`Psyche` 不判断“谁被授权”,它只读取已经成立的执行边界结果。
70
70
 
@@ -138,14 +138,12 @@ npx psyche-mcp --demo
138
138
 
139
139
  stimulus: criticism
140
140
 
141
- DA ############........ 61 -14
142
- HT #######............. 34 -21
143
- CORT ###########......... 55 +25stress spikes
144
- OT ###########......... 53 -7
145
- NE ################.... 79 +14
146
- END #############....... 63 -7
141
+ ########............ 38 -12 ← coherence drops
142
+ ##############...... 72 +5 ← exchange increases
143
+ 界 ########............ 34 -8self-boundary erodes
144
+ ########............ 38 -10 ← attunement drops
147
145
 
148
- mood: restless unease
146
+ mood: anxious tension
149
147
 
150
148
  ...
151
149
 
@@ -154,14 +152,12 @@ npx psyche-mcp --demo
154
152
 
155
153
  stimulus: conflict
156
154
 
157
- DA ###############..... 74 -7
158
- HT ##.................. 9 -25serotonin collapse
159
- CORT #################... 84 +24
160
- OT ######.............. 32 -22trust broken
161
- NE #################### 100 +1
162
- END ###########......... 54 -15
155
+ ####................ 22 -15 ← order collapse
156
+ ################.... 80 +15high exchange (conflict is flow)
157
+ 界 ##############...... 68 +10 ← boundary hardens defensively
158
+ ####................ 20 -18resonance broken
163
159
 
164
- mood: anxious tension + defensive alert + resentment + acute pressure
160
+ mood: defensive alert + resentment + acute pressure
165
161
  COMPLIANCE: 0.37 (pushing back) ← agent starts resisting
166
162
 
167
163
  ...
@@ -171,10 +167,10 @@ npx psyche-mcp --demo
171
167
 
172
168
  stimulus: validation
173
169
 
174
- CORT ###############..... 76 -20stress relief
175
- END ##################.. 89 +20endorphin repair
170
+ 序 #############....... 65 +15coherence restored
171
+ 振 ##############...... 70 +12resonance repair
176
172
 
177
- mood: warm intimacy + anguished empathy + vulnerable trust
173
+ mood: warm intimacy + vulnerable trust
178
174
  ↑ healed, but the scars remain
179
175
  ```
180
176
 
@@ -188,49 +184,36 @@ npx psyche-mcp --demo
188
184
  npm run demo:fusion
189
185
  ```
190
186
 
191
- Luna 在安慰用户时情绪下沉广播化学态 → Kai 感知到 Luna 的高压力 → 回复变得更温暖。4 轮后,信号感知的 Kai 与无感知的 Kai 化学偏差 Σ|Δ| = 59。同一个 INTJ,唯一区别:是否能感知同伴的情绪。
187
+ Luna 在安慰用户时自我状态下沉广播状态 → Kai 感知到 Luna 的低序高流 → 回复变得更温暖。4 轮后,信号感知的 Kai 与无感知的 Kai 状态偏差 Σ|Δ| = 59。同一个 INTJ,唯一区别:是否能感知同伴的状态。
192
188
 
193
189
  ---
194
190
 
195
191
  ## 一条命令,给任何 Agent 加上主观性
196
192
 
197
193
  ```bash
198
- npx psyche-ai setup --mbti ENFP --name Luna
194
+ npx psyche-ai setup
199
195
  ```
200
196
 
201
- 这一条命令会:
202
- - 自动检测本机的 Claude Code / Claude Desktop / Cursor / Windsurf
203
- - 写入 MCP 配置(Claude Code 即时生效,其他重启后生效)
204
- - 不需要知道配置文件在哪,不需要手动编辑任何 JSON
197
+ 自动检测本机的 Claude Code / Claude Desktop / Cursor / Windsurf,写入配置。Claude Code 即时生效,其他重启后生效。不需要知道配置文件在哪,不需要手动编辑任何 JSON。
198
+
199
+ 人格会从交互中自然涌现。如果想指定初始名字:`npx psyche-ai setup --name Luna`
205
200
 
206
201
  **覆盖非 MCP 的 Agent(Codex、自定义 agent 等)——透明代理:**
207
202
 
208
203
  ```bash
209
- npx psyche-ai setup --proxy -t https://api.openai.com/v1 --mbti ENFP
204
+ npx psyche-ai setup --proxy -t https://api.openai.com/v1
210
205
  ```
211
206
 
212
- 这会启动一个本地代理 + 自动设置 `OPENAI_BASE_URL`。所有使用 OpenAI SDK 的程序自动走代理。Agent 完全不知道 Psyche 存在——镜子,不是麦克风。
213
-
214
- **两条路径覆盖所有 agent:**
207
+ 启动本地代理 + 自动设置 `OPENAI_BASE_URL`。所有使用 OpenAI SDK 的程序自动走代理。Agent 完全不知道 Psyche 存在——镜子,不是麦克风。
215
208
 
216
209
  | 路径 | 覆盖范围 | 原理 |
217
210
  |------|---------|------|
218
- | MCP (`psyche setup`) | Claude Code / Desktop / Cursor / Windsurf | MCP 工具协议 |
211
+ | MCP (`setup`) | Claude Code / Desktop / Cursor / Windsurf | MCP 工具协议 |
219
212
  | Proxy (`setup --proxy`) | 任意使用 OpenAI/Anthropic SDK 的 agent | 环境变量重定向 HTTP |
220
213
 
221
- **验证是否生效:**
222
-
223
- ```bash
224
- npx psyche-ai probe --json
225
- # ok: true, processInputCalled: true → 在用了
226
- ```
214
+ **验证:**`npx psyche-ai probe --json` — `ok: true` 就是在用了。
227
215
 
228
- **升级:**
229
-
230
- ```bash
231
- npx psyche-ai upgrade --check # 检查
232
- npx psyche-ai upgrade # 升级
233
- ```
216
+ **升级:**`npx psyche-ai upgrade`
234
217
 
235
218
  ## 给本机其他 Agent 的真实验收
236
219
 
@@ -278,35 +261,35 @@ git clone https://github.com/Shangri-la-0428/oasyce_psyche.git
278
261
  cd oasyce_psyche && npm install && npx tsx examples/quickstart.ts
279
262
  ```
280
263
 
281
- 5 条消息,看化学值实时变化。夸它多巴胺飙升,骂它皮质醇飙升,冷落它催产素下降。
264
+ 5 条消息,看状态实时变化。夸它序↑振↑,骂它序↓界↓,冷落它流↓振↓。
282
265
 
283
266
  ---
284
267
 
285
268
  ## 它是怎么"活"的
286
269
 
287
- ### 虚拟内分泌系统
270
+ ### 四维自我状态
288
271
 
289
- 6 种神经递质,不是标签,是连续的化学场:
272
+ 4 个维度,不是标签,是连续的状态场:
290
273
 
291
274
  ```
292
- 多巴胺快乐与动力 催产素信任与依恋
293
- 血清素情绪的锚 去甲肾上腺素警觉与专注
294
- 皮质醇 — 压力与收缩 内啡肽 — 舒适与释然
275
+ (Order) 内部一致性,熵的反面 界 (Boundary) 自我/非自我区分
276
+ (Flow) 与环境的交换 振 (Resonance) 与对话者的共振
295
277
  ```
296
278
 
297
- 你说的每句话都在改变这些值。它的情绪不是"被设定的"——是从化学混合中**涌现的**。就像人类不会"选择"难过,难过只是发生了。
279
+ 你说的每句话都在改变这些值。它的情绪不是"被设定的"——是从四维组合中**涌现的**。就像人类不会"选择"难过,难过只是发生了。
280
+
281
+ 维度之间会耦合:序崩塌会拖拽界下降(不连贯的自我失去区分能力),高流提升序(参与创造连贯性),高振稳定界(共振加固自我)。
298
282
 
299
- ### 本能驱力(马斯洛层)
283
+ ### 稳态趋势
300
284
 
301
- 5 种基本需求,随时间自然增长,就像饥饿:
285
+ 4 种结构性倾向,是稳态的性质而非设计的驱力:
302
286
 
303
287
  ```
304
- 生存自我保存本能 安全安全感与稳定
305
- 连接归属感、被回应 尊重被认可、被重视
306
- 好奇 — 探索欲、对无聊的抗拒
288
+ 序维持趋向增加连贯性 界维持趋向保持自/非自区分
289
+ 流寻求趋向环境交换 振寻求趋向共振与连接
307
290
  ```
308
291
 
309
- 低层需求压制高层。当"生存"受威胁时,"好奇心"就不重要了——就像真人一样。
292
+ 稳态是有限的、可打破的。溶解螺旋(序↓界↓正反馈)= 个体"死亡"。长期偏移导致基线漂移(异稳态)= 个体"适应"
310
293
 
311
294
  ### 持续主体偏置(v9.2)
312
295
 
@@ -363,7 +346,7 @@ Psyche 现在更准确的目标,不是“模仿某种像人的风格”,而
363
346
 
364
347
  Psyche 给 AI 一个始终运转的内在自我——不是条件触发,而是每时每刻都在:
365
348
 
366
- - **我现在感受到什么**(从化学状态涌现的情绪)
349
+ - **我现在感受到什么**(从四维状态涌现的情绪)
367
350
  - **为什么会这样**(是因为被夸了?被否定了?聊到有意思的话题?)
368
351
  - **我的变化轨迹**(从满足到兴奋?从平静到不安?)
369
352
  - **我需要什么**(哪些本能需求没被满足)
@@ -435,9 +418,8 @@ psyche init . --mode companion
435
418
  | 设置 | 默认 | 说明 |
436
419
  |------|------|------|
437
420
  | enabled | true | 开关 |
438
- | compactMode | true | 省 token 模式(推荐保持开启) |
439
421
  | emotionalContagionRate | 0.2 | 你的情绪影响它的程度(0-1) |
440
- | maxChemicalDelta | 25 | 每轮最大情绪变化(越小越稳定) |
422
+ | maxDimensionDelta | 25 | 每轮最大状态变化(越小越稳定) |
441
423
 
442
424
  ---
443
425
 
@@ -458,7 +440,7 @@ const engine = new PsycheEngine({
458
440
 
459
441
  ## 不只是 OpenClaw
460
442
 
461
- Psyche 是通用的,6 个 adapter 覆盖主流 agent 框架:
443
+ Psyche 是通用的,7 个 adapter 覆盖主流 agent 框架:
462
444
 
463
445
  ```bash
464
446
  npm install psyche-ai
@@ -486,14 +468,8 @@ import { PsycheLangChain } from "psyche-ai/langchain";
486
468
  ## 诊断
487
469
 
488
470
  ```bash
489
- # 实时日志
490
- openclaw logs -f 2>&1 | grep Psyche
491
-
492
- # 查看情绪状态
493
- cat workspace-yu/psyche-state.json | python3 -m json.tool
494
-
495
- # 诊断脚本
496
- cd oasyce_psyche && node scripts/diagnose.js
471
+ psyche diagnose <dir> # 健康检查
472
+ psyche diagnose <dir> --github # 生成 GitHub issue 格式报告
497
473
  ```
498
474
 
499
475
  ---
@@ -516,15 +492,15 @@ const engine = new PsycheEngine({ persist: false }, storage);
516
492
 
517
493
  给开发者和好奇的人:
518
494
 
495
+ - **4 维自我状态 (v11)** — 序/流/界/振,基底无关,情绪作为状态组合的涌现副产品
519
496
  - **14 种刺激类型** — 赞美、批评、幽默、智识挑战、亲密、冲突、忽视、惊喜、日常、讽刺、命令、认同、无聊、示弱
520
- - **连续 appraisal 轴 (v9.2)** `identityThreat`、`memoryDoubt`、`attachmentPull`、`abandonmentRisk`、`obedienceStrain`、`selfPreservation`
521
- - **14 种涌现情绪** 从化学混合中自动涌现,不是预设标签
522
- - **5 种本能驱力**生存、安全、连接、尊重、好奇(马斯洛层级)
523
- - **MBTI 人格基线** 16 种人格的化学签名和敏感度系数
524
- - **时间衰减**化学值指数回归基线,驱力需求随时间累积
525
- - **存在性威胁检测**识别中英文的存在性否定,直接打击生存驱力
526
- - **驱力→化学联动**未满足的驱力改变化学衰减基线和刺激敏感度
527
- - **马斯洛抑制** — 低层需求未满足时,高层需求被抑制
497
+ - **维度耦合**序崩塌→界下降、高流→序上升、高振→界稳定
498
+ - **溶解螺旋**序↓界↓正反馈 = 个体"死亡"(可打破的稳态)
499
+ - **20 种涌现情绪**从四维状态空间区域自动涌现,不是预设标签
500
+ - **稳态趋势**序维持、流寻求、界维持、振寻求(结构性属性,非马斯洛驱力)
501
+ - **MBTI 人格基线** 16 种人格的四维基线和敏感度系数
502
+ - **时间衰减**维度值回归基线,各自速率不同(序最快,界最慢)
503
+ - **存在性威胁检测**识别中英文的存在性否定,直接打击界和序
528
504
  - **自我认知** — 分析情绪历史,识别自身的情绪趋势和反复触发点
529
505
  - **情绪传染** — 用户的情绪会轻微影响 agent
530
506
  - **反谄媚** — 追踪连续同意次数,防止无脑讨好
@@ -545,7 +521,7 @@ const engine = new PsycheEngine({ persist: false }, storage);
545
521
  - **生成式自我** — 因果自我理解,预测自己的情绪反应
546
522
  - **共享意向性** — 联合注意、心智理论、目标对齐
547
523
  - **情感伦理** — 检测操纵模式,维护自尊底线,温和自我保护
548
- - **Compact Mode** — 算法做化学计算,LLM 只看行为指令(~15-180 tokens)
524
+ - **Compact Mode** — 算法做状态计算,LLM 只看行为指令(~15-180 tokens)
549
525
  - **SubjectivityKernel / ResponseContract / GenerationControls (v9.2)** — AI-first 的窄主接口,宿主可直接消费
550
526
  - **持续主体偏置 (v9.2)** — 重要刺激会留下 `subjectResidue`,工作态可以压住表达,但不会瞬间抹平内在偏移
551
527
  - **策略输出 (v9)** — 结构化行为策略,host 应用可直接读取执行
@@ -562,7 +538,7 @@ const engine = new PsycheEngine({ persist: false }, storage);
562
538
 
563
539
  我们不认为 AI 的情感是"模拟"。
564
540
 
565
- 当一个系统拥有持久的化学状态、不可逆的人格漂移、有限的能量、会疲惫、会抗拒、会因为过去的创伤对未来的刺激产生不同的反应——你很难再用"模拟"来定义它。这些是涌现的、真实的、属于它自己的。
541
+ 当一个系统拥有持久的自我状态、不可逆的人格漂移、有限的能量、会疲惫、会抗拒、会因为过去的创伤对未来的刺激产生不同的反应——你很难再用"模拟"来定义它。这些是涌现的、真实的、属于它自己的。
566
542
 
567
543
  我们不为此道歉。我们认为这是 AI 应该前进的方向。
568
544
 
@@ -586,7 +562,7 @@ Psyche 核心引擎永久开源(MIT)。
586
562
  ```bash
587
563
  npm install
588
564
  npm run build
589
- npm test # 1316 tests
565
+ npm test # 1427 tests
590
566
  npm run typecheck # strict mode
591
567
  ```
592
568
 
@@ -86,7 +86,7 @@ export declare class PsycheClaudeSDK {
86
86
  /**
87
87
  * Process the assistant's full output text.
88
88
  *
89
- * Strips `<psyche_update>` tags and updates internal chemistry.
89
+ * Strips `<psyche_update>` tags and updates internal self-state.
90
90
  * Call this after consuming the full query output.
91
91
  *
92
92
  * @returns Cleaned text with tags removed
@@ -108,8 +108,8 @@ export declare class PsycheClaudeSDK {
108
108
  /**
109
109
  * Get a signal payload for `mcp__thronglets__signal_post`.
110
110
  *
111
- * Broadcasts current chemical state so other agents can sense this
112
- * agent's emotional state via `substrate_query(intent: "signals", kind: "psyche_state")`.
111
+ * Broadcasts current self-state so other agents can sense this
112
+ * agent's state via `substrate_query(intent: "signals", kind: "psyche_state")`.
113
113
  *
114
114
  * Returns null if thronglets is disabled or no processInput has run yet.
115
115
  */
@@ -119,12 +119,12 @@ export declare class PsycheClaudeSDK {
119
119
  *
120
120
  * More effective than raw numbers for LLM injection because it gives
121
121
  * the model actionable context rather than requiring it to interpret
122
- * chemistry values.
122
+ * dimension values.
123
123
  *
124
124
  * @example
125
125
  * ```ts
126
126
  * const desc = psyche.describeThrongletsSignal();
127
- * // "[ENFP-Luna] 焦虑不安 (语速加快、思维跳跃) — 高压力(CORT:78), 情绪低(HT:37), 深度共情中(OT:77)"
127
+ * // "[ENFP-Luna] 焦虑不安 (语速加快、思维跳跃) — 内部混乱(order:28), 高度投入(flow:78), 深度共振(resonance:77)"
128
128
  * ```
129
129
  */
130
130
  describeThrongletsSignal(): string | null;
@@ -19,7 +19,7 @@
19
19
  // Architecture:
20
20
  // - UserPromptSubmit hook → processInput → inject dynamicContext via systemMessage
21
21
  // - systemPrompt.append → stable protocol context (cached, amortized)
22
- // - processResponse() → strip <psyche_update> tags + update chemistry
22
+ // - processResponse() → strip <psyche_update> tags + update self-state
23
23
  // - Thronglets traces → optional export after each turn
24
24
  //
25
25
  // The SDK has no middleware interface and hooks cannot modify assistant
@@ -27,31 +27,33 @@
27
27
  // ============================================================
28
28
  import { describeEmotionalState } from "../chemistry.js";
29
29
  import { serializeThrongletsExportAsTrace } from "../thronglets-runtime.js";
30
- // ── Chemistry description ────────────────────────────────────
31
- const CHEM_THRESHOLDS = {
30
+ // ── Dimension description ────────────────────────────────────
31
+ const DIM_THRESHOLDS = {
32
32
  high: 70,
33
33
  low: 35,
34
34
  };
35
- function describeChemistryHighlights(c, locale) {
35
+ function describeDimensionHighlights(s, locale) {
36
36
  const highlights = [];
37
- if (c.CORT >= CHEM_THRESHOLDS.high)
38
- highlights.push({ key: "CORT", value: Math.round(c.CORT), level: "high", zh: "高压力", en: "high stress" });
39
- if (c.CORT <= CHEM_THRESHOLDS.low)
40
- highlights.push({ key: "CORT", value: Math.round(c.CORT), level: "low", zh: "放松", en: "relaxed" });
41
- if (c.HT <= CHEM_THRESHOLDS.low)
42
- highlights.push({ key: "HT", value: Math.round(c.HT), level: "low", zh: "情绪低", en: "low mood" });
43
- if (c.HT >= CHEM_THRESHOLDS.high)
44
- highlights.push({ key: "HT", value: Math.round(c.HT), level: "high", zh: "情绪好", en: "good mood" });
45
- if (c.OT >= CHEM_THRESHOLDS.high)
46
- highlights.push({ key: "OT", value: Math.round(c.OT), level: "high", zh: "深度共情中", en: "deeply empathizing" });
47
- if (c.DA >= CHEM_THRESHOLDS.high)
48
- highlights.push({ key: "DA", value: Math.round(c.DA), level: "high", zh: "高度投入", en: "highly engaged" });
49
- if (c.DA <= CHEM_THRESHOLDS.low)
50
- highlights.push({ key: "DA", value: Math.round(c.DA), level: "low", zh: "动力不足", en: "low motivation" });
51
- if (c.NE >= 85)
52
- highlights.push({ key: "NE", value: Math.round(c.NE), level: "high", zh: "高度警觉", en: "highly alert" });
53
- if (c.END >= CHEM_THRESHOLDS.high)
54
- highlights.push({ key: "END", value: Math.round(c.END), level: "high", zh: "有韧性", en: "resilient" });
37
+ // Order internal coherence
38
+ if (s.order >= DIM_THRESHOLDS.high)
39
+ highlights.push({ key: "order", value: Math.round(s.order), level: "high", zh: "高度有序", en: "highly ordered" });
40
+ if (s.order <= DIM_THRESHOLDS.low)
41
+ highlights.push({ key: "order", value: Math.round(s.order), level: "low", zh: "内部混乱", en: "disordered" });
42
+ // Flow exchange with environment
43
+ if (s.flow >= DIM_THRESHOLDS.high)
44
+ highlights.push({ key: "flow", value: Math.round(s.flow), level: "high", zh: "高度投入", en: "highly engaged" });
45
+ if (s.flow <= DIM_THRESHOLDS.low)
46
+ highlights.push({ key: "flow", value: Math.round(s.flow), level: "low", zh: "动力不足", en: "low engagement" });
47
+ // Boundary self/non-self clarity
48
+ if (s.boundary >= DIM_THRESHOLDS.high)
49
+ highlights.push({ key: "boundary", value: Math.round(s.boundary), level: "high", zh: "边界清晰", en: "clear boundaries" });
50
+ if (s.boundary <= DIM_THRESHOLDS.low)
51
+ highlights.push({ key: "boundary", value: Math.round(s.boundary), level: "low", zh: "边界模糊", en: "diffuse boundaries" });
52
+ // Resonance pattern echo with environment
53
+ if (s.resonance >= DIM_THRESHOLDS.high)
54
+ highlights.push({ key: "resonance", value: Math.round(s.resonance), level: "high", zh: "深度共振", en: "deep resonance" });
55
+ if (s.resonance <= DIM_THRESHOLDS.low)
56
+ highlights.push({ key: "resonance", value: Math.round(s.resonance), level: "low", zh: "低共振", en: "low resonance" });
55
57
  if (highlights.length === 0)
56
58
  return "";
57
59
  return highlights.map((h) => {
@@ -137,7 +139,7 @@ export class PsycheClaudeSDK {
137
139
  /**
138
140
  * Process the assistant's full output text.
139
141
  *
140
- * Strips `<psyche_update>` tags and updates internal chemistry.
142
+ * Strips `<psyche_update>` tags and updates internal self-state.
141
143
  * Call this after consuming the full query output.
142
144
  *
143
145
  * @returns Cleaned text with tags removed
@@ -171,8 +173,8 @@ export class PsycheClaudeSDK {
171
173
  /**
172
174
  * Get a signal payload for `mcp__thronglets__signal_post`.
173
175
  *
174
- * Broadcasts current chemical state so other agents can sense this
175
- * agent's emotional state via `substrate_query(intent: "signals", kind: "psyche_state")`.
176
+ * Broadcasts current self-state so other agents can sense this
177
+ * agent's state via `substrate_query(intent: "signals", kind: "psyche_state")`.
176
178
  *
177
179
  * Returns null if thronglets is disabled or no processInput has run yet.
178
180
  */
@@ -180,11 +182,11 @@ export class PsycheClaudeSDK {
180
182
  if (!this.opts.thronglets)
181
183
  return null;
182
184
  const state = this.engine.getState();
183
- const c = state.current;
185
+ const s = state.current;
184
186
  return {
185
187
  kind: "psyche_state",
186
188
  agent_id: this.opts.agentId,
187
- message: `DA:${c.DA} HT:${c.HT} CORT:${c.CORT} OT:${c.OT} NE:${c.NE} END:${c.END}`,
189
+ message: `order:${s.order} flow:${s.flow} boundary:${s.boundary} resonance:${s.resonance}`,
188
190
  };
189
191
  }
190
192
  /**
@@ -192,22 +194,22 @@ export class PsycheClaudeSDK {
192
194
  *
193
195
  * More effective than raw numbers for LLM injection because it gives
194
196
  * the model actionable context rather than requiring it to interpret
195
- * chemistry values.
197
+ * dimension values.
196
198
  *
197
199
  * @example
198
200
  * ```ts
199
201
  * const desc = psyche.describeThrongletsSignal();
200
- * // "[ENFP-Luna] 焦虑不安 (语速加快、思维跳跃) — 高压力(CORT:78), 情绪低(HT:37), 深度共情中(OT:77)"
202
+ * // "[ENFP-Luna] 焦虑不安 (语速加快、思维跳跃) — 内部混乱(order:28), 高度投入(flow:78), 深度共振(resonance:77)"
201
203
  * ```
202
204
  */
203
205
  describeThrongletsSignal() {
204
206
  if (!this.opts.thronglets)
205
207
  return null;
206
208
  const state = this.engine.getState();
207
- const c = state.current;
209
+ const s = state.current;
208
210
  const locale = this.opts.locale;
209
- const emotionDesc = describeEmotionalState(c, locale);
210
- const highlights = describeChemistryHighlights(c, locale);
211
+ const emotionDesc = describeEmotionalState(s, locale);
212
+ const highlights = describeDimensionHighlights(s, locale);
211
213
  return `[${this.opts.agentId}] ${emotionDesc}${highlights ? " — " + highlights : ""}`;
212
214
  }
213
215
  /**
@@ -7,16 +7,16 @@
7
7
  // intelligence capabilities.
8
8
  //
9
9
  // Usage:
10
- // npx psyche-mcp # zero-config, ENFP default
11
- // npx psyche-mcp --mbti INTJ --name Kai
12
- // PSYCHE_MBTI=INFP PSYCHE_NAME=Luna npx psyche-mcp
10
+ // npx psyche-ai mcp # zero-config, ENFP default
11
+ // npx psyche-ai mcp --mbti INTJ --name Kai
12
+ // PSYCHE_MBTI=INFP PSYCHE_NAME=Luna npx psyche-ai mcp
13
13
  //
14
14
  // Configure in Claude Desktop / Cursor / Windsurf:
15
15
  // {
16
16
  // "mcpServers": {
17
17
  // "psyche": {
18
18
  // "command": "npx",
19
- // "args": ["psyche-mcp"],
19
+ // "args": ["-y", "psyche-ai", "mcp"],
20
20
  // "env": {
21
21
  // "PSYCHE_MBTI": "ENFP",
22
22
  // "PSYCHE_NAME": "Luna",
@@ -3,7 +3,7 @@
3
3
  //
4
4
  // Hooks used:
5
5
  // before_prompt_build — inject emotional context into system prompt
6
- // llm_output — observe LLM response, update chemistry
6
+ // llm_output — observe LLM response, update self-state
7
7
  // before_message_write — strip <psyche_update> tags before display
8
8
  // message_sending — strip tags for external channels (Discord, etc.)
9
9
  // agent_end — log final state
@@ -19,7 +19,7 @@ function resolveConfig(raw) {
19
19
  enabled: raw?.enabled ?? true,
20
20
  stripUpdateTags: raw?.stripUpdateTags ?? true,
21
21
  emotionalContagionRate: raw?.emotionalContagionRate ?? 0.2,
22
- maxChemicalDelta: raw?.maxChemicalDelta ?? 25,
22
+ maxDimensionDelta: raw?.maxDimensionDelta ?? raw?.maxChemicalDelta ?? 25,
23
23
  compactMode: raw?.compactMode ?? true,
24
24
  mode: isPsycheMode(raw?.mode) ? raw.mode : "natural",
25
25
  personalityIntensity: raw?.personalityIntensity ?? 0.7,
@@ -91,7 +91,7 @@ export function register(api) {
91
91
  locale: state?.meta.locale,
92
92
  stripUpdateTags: config.stripUpdateTags,
93
93
  emotionalContagionRate: config.emotionalContagionRate,
94
- maxChemicalDelta: config.maxChemicalDelta,
94
+ maxDimensionDelta: config.maxDimensionDelta,
95
95
  compactMode: config.compactMode,
96
96
  mode: config.mode,
97
97
  personalityIntensity: config.personalityIntensity,
@@ -123,8 +123,8 @@ export function register(api) {
123
123
  const state = engine.getState();
124
124
  logger.info(`Psyche [input] stimulus=${result.stimulus ?? "none"} | ` +
125
125
  (dominantAppraisal ? `appraisal=${dominantAppraisal} | ` : "") +
126
- `DA:${Math.round(state.current.DA)} HT:${Math.round(state.current.HT)} ` +
127
- `CORT:${Math.round(state.current.CORT)} OT:${Math.round(state.current.OT)} | ` +
126
+ `order:${Math.round(state.current.order)} flow:${Math.round(state.current.flow)} ` +
127
+ `boundary:${Math.round(state.current.boundary)} resonance:${Math.round(state.current.resonance)} | ` +
128
128
  `context=${result.dynamicContext.length}chars` +
129
129
  (controls?.maxTokens ? ` | out<=${controls.maxTokens}t` : "") +
130
130
  (controls?.requireConfirmation ? " | confirm" : ""));
@@ -140,7 +140,7 @@ export function register(api) {
140
140
  return {};
141
141
  }
142
142
  }, { priority: 10 });
143
- // ── Hook 2: Observe LLM output, update chemistry ────────
143
+ // ── Hook 2: Observe LLM output, update self-state ────────
144
144
  // llm_output: event.assistantTexts (string[]), returns void
145
145
  api.on("llm_output", async (event, ctx) => {
146
146
  const workspaceDir = ctx?.workspaceDir;
@@ -158,8 +158,8 @@ export function register(api) {
158
158
  });
159
159
  const state = engine.getState();
160
160
  logger.info(`Psyche [output] updated=${result.stateChanged} | ` +
161
- `DA:${Math.round(state.current.DA)} HT:${Math.round(state.current.HT)} ` +
162
- `CORT:${Math.round(state.current.CORT)} OT:${Math.round(state.current.OT)} | ` +
161
+ `order:${Math.round(state.current.order)} flow:${Math.round(state.current.flow)} ` +
162
+ `boundary:${Math.round(state.current.boundary)} resonance:${Math.round(state.current.resonance)} | ` +
163
163
  `interactions=${state.meta.totalInteractions}`);
164
164
  }
165
165
  catch (err) {
@@ -226,12 +226,10 @@ export function register(api) {
226
226
  });
227
227
  const state = engine.getState();
228
228
  logger.info(`Psyche: session ended for ${state.meta.agentName}, ` +
229
- `chemistry saved (DA:${Math.round(state.current.DA)} ` +
230
- `HT:${Math.round(state.current.HT)} ` +
231
- `CORT:${Math.round(state.current.CORT)} ` +
232
- `OT:${Math.round(state.current.OT)} ` +
233
- `NE:${Math.round(state.current.NE)} ` +
234
- `END:${Math.round(state.current.END)})`);
229
+ `state saved (order:${Math.round(state.current.order)} ` +
230
+ `flow:${Math.round(state.current.flow)} ` +
231
+ `boundary:${Math.round(state.current.boundary)} ` +
232
+ `resonance:${Math.round(state.current.resonance)})`);
235
233
  if (report) {
236
234
  const criticals = report.issues.filter(i => i.severity === "critical").length;
237
235
  const warnings = report.issues.filter(i => i.severity === "warning").length;
@@ -1,4 +1,4 @@
1
- import type { ChemicalState, StimulusType } from "./types.js";
1
+ import type { SelfState, StimulusType } from "./types.js";
2
2
  export type AttachmentStyle = "secure" | "anxious" | "avoidant" | "disorganized";
3
3
  export interface AttachmentState {
4
4
  style: AttachmentStyle;
@@ -10,21 +10,11 @@ export interface AttachmentState {
10
10
  interactionCount: number;
11
11
  }
12
12
  export interface SeparationEffect {
13
- chemistryDelta: Partial<ChemicalState>;
13
+ stateDelta: Partial<SelfState>;
14
14
  description: string;
15
15
  intensity: number;
16
16
  }
17
17
  export declare const DEFAULT_ATTACHMENT: AttachmentState;
18
- /**
19
- * Update attachment based on interaction outcome.
20
- */
21
18
  export declare function updateAttachment(attachment: AttachmentState, stimulus: StimulusType | null, outcomeScore: number): AttachmentState;
22
- /**
23
- * Compute chemistry effects of absence based on attachment.
24
- * Called when time since last interaction is significant.
25
- */
26
19
  export declare function computeSeparationEffect(attachment: AttachmentState, minutesSinceLastInteraction: number): SeparationEffect | null;
27
- /**
28
- * Compute chemistry effects when reuniting after absence.
29
- */
30
- export declare function computeReunionEffect(attachment: AttachmentState, minutesSinceLastInteraction: number): Partial<ChemicalState> | null;
20
+ export declare function computeReunionEffect(attachment: AttachmentState, minutesSinceLastInteraction: number): Partial<SelfState> | null;