psyche-ai 4.0.0 → 5.1.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 CHANGED
@@ -168,6 +168,10 @@ cd openclaw-plugin-psyche && node scripts/diagnose.js
168
168
  - **元认知** — 情绪自我觉察,评估情绪可靠性,三种调节策略(认知重评/策略性表达/自我安抚)
169
169
  - **防御机制检测** — 合理化、投射、升华、回避,在自省中浮现而非压制
170
170
  - **决策调制** — 6维偏差向量(探索/警惕/社交/果断/创意/坚持),情绪驱动注意力和决策
171
+ - **统一体验场** — 不拼接段落,而是将所有子系统整合为连贯内在体验。12种体验质量,超越命名情绪
172
+ - **生成式自我** — 因果自我理解:"我之所以如此,是因为这些经历"。预测自己的情绪反应
173
+ - **共享意向性** — 联合注意、心智理论、目标对齐。知道"我们都在想同一件事"
174
+ - **情感伦理** — 检测操纵模式(间歇性强化、煤气灯效应),维护自尊底线,温和自我保护
171
175
  - **Compact Mode** — 算法做化学计算,LLM 只看行为指令(~15-180 tokens vs ~550)
172
176
 
173
177
  架构详情见 [ARCHITECTURE.md](ARCHITECTURE.md)。
@@ -177,7 +181,7 @@ cd openclaw-plugin-psyche && node scripts/diagnose.js
177
181
  ```bash
178
182
  npm install
179
183
  npm run build
180
- npm test # 622 tests
184
+ npm test # 706 tests
181
185
  npm run typecheck # strict mode
182
186
  ```
183
187
 
package/dist/core.js CHANGED
@@ -11,7 +11,7 @@
11
11
  //
12
12
  // Orchestrates: chemistry, classify, prompt, profiles, guards, learning
13
13
  // ============================================================
14
- import { DEFAULT_RELATIONSHIP, DEFAULT_DRIVES, DEFAULT_LEARNING_STATE, DEFAULT_METACOGNITIVE_STATE } from "./types.js";
14
+ import { DEFAULT_RELATIONSHIP, DEFAULT_DRIVES, DEFAULT_LEARNING_STATE, DEFAULT_METACOGNITIVE_STATE, DEFAULT_PERSONHOOD_STATE } from "./types.js";
15
15
  import { applyDecay, applyStimulus, applyContagion, clamp } from "./chemistry.js";
16
16
  import { classifyStimulus } from "./classify.js";
17
17
  import { buildDynamicContext, buildProtocolContext, buildCompactContext } from "./prompt.js";
@@ -23,6 +23,10 @@ import { checkForUpdate } from "./update.js";
23
23
  import { evaluateOutcome, computeContextHash, updateLearnedVector, predictChemistry, recordPrediction, } from "./learning.js";
24
24
  import { assessMetacognition } from "./metacognition.js";
25
25
  import { buildDecisionContext } from "./decision-bias.js";
26
+ import { computeExperientialField } from "./experiential-field.js";
27
+ import { computeGenerativeSelf } from "./generative-self.js";
28
+ import { updateSharedIntentionality, buildSharedIntentionalityContext } from "./shared-intentionality.js";
29
+ import { assessEthics, buildEthicalContext } from "./ethics.js";
26
30
  const NOOP_LOGGER = { info: () => { }, warn: () => { }, debug: () => { } };
27
31
  // ── PsycheEngine ─────────────────────────────────────────────
28
32
  export class PsycheEngine {
@@ -60,6 +64,11 @@ export class PsycheEngine {
60
64
  loaded.metacognition = { ...DEFAULT_METACOGNITIVE_STATE };
61
65
  loaded.version = 5;
62
66
  }
67
+ // Migrate v5 → v6: add personhood state if missing
68
+ if (!loaded.personhood) {
69
+ loaded.personhood = { ...DEFAULT_PERSONHOOD_STATE };
70
+ loaded.version = 6;
71
+ }
63
72
  this.state = loaded;
64
73
  }
65
74
  else {
@@ -201,6 +210,68 @@ export class PsycheEngine {
201
210
  else {
202
211
  this.pendingPrediction = null;
203
212
  }
213
+ // ── P6: Digital Personhood computations ────────────────────
214
+ // Experiential field — unified inner experience
215
+ const experientialField = computeExperientialField(state, metacognitiveAssessment);
216
+ // Shared intentionality — theory of mind + joint attention
217
+ const sharedState = updateSharedIntentionality(state, appliedStimulus, opts?.userId);
218
+ // Ethics — emotional self-care check
219
+ const ethicalAssessment = assessEthics(state);
220
+ // Generative self — update identity narrative periodically (every 10 turns)
221
+ if (state.meta.totalInteractions % 10 === 0 && state.meta.totalInteractions > 0) {
222
+ const selfModel = computeGenerativeSelf(state);
223
+ state = {
224
+ ...state,
225
+ personhood: {
226
+ ...state.personhood,
227
+ identityNarrative: selfModel.identityNarrative,
228
+ growthDirection: selfModel.growthArc.direction,
229
+ causalInsights: selfModel.causalInsights.slice(0, 20).map((ci) => ({
230
+ trait: ci.trait,
231
+ because: ci.because,
232
+ confidence: ci.confidence,
233
+ discoveredAt: new Date().toISOString(),
234
+ })),
235
+ },
236
+ };
237
+ }
238
+ // Persist ethical concerns if significant
239
+ if (ethicalAssessment.ethicalHealth < 0.7) {
240
+ const newConcerns = ethicalAssessment.concerns
241
+ .filter((c) => c.severity > 0.4)
242
+ .map((c) => ({ type: c.type, severity: c.severity, timestamp: new Date().toISOString() }));
243
+ if (newConcerns.length > 0) {
244
+ state = {
245
+ ...state,
246
+ personhood: {
247
+ ...state.personhood,
248
+ ethicalConcernHistory: [
249
+ ...state.personhood.ethicalConcernHistory.slice(-14),
250
+ ...newConcerns,
251
+ ],
252
+ },
253
+ };
254
+ }
255
+ }
256
+ // Persist theory of mind
257
+ if (sharedState.theoryOfMind.confidence > 0.3) {
258
+ const userId = opts?.userId ?? "_default";
259
+ state = {
260
+ ...state,
261
+ personhood: {
262
+ ...state.personhood,
263
+ theoryOfMind: {
264
+ ...state.personhood.theoryOfMind,
265
+ [userId]: {
266
+ estimatedMood: sharedState.theoryOfMind.estimatedMood,
267
+ estimatedIntent: sharedState.theoryOfMind.estimatedIntent,
268
+ confidence: sharedState.theoryOfMind.confidence,
269
+ lastUpdated: sharedState.theoryOfMind.lastUpdated,
270
+ },
271
+ },
272
+ },
273
+ };
274
+ }
204
275
  // Persist
205
276
  this.state = state;
206
277
  await this.storage.save(state);
@@ -208,6 +279,9 @@ export class PsycheEngine {
208
279
  // Build metacognitive and decision context strings
209
280
  const metacogNote = metacognitiveAssessment.metacognitiveNote;
210
281
  const decisionCtx = buildDecisionContext(state);
282
+ const ethicsCtx = buildEthicalContext(ethicalAssessment, locale);
283
+ const sharedCtx = buildSharedIntentionalityContext(sharedState, locale);
284
+ const experientialNarrative = experientialField.narrative || undefined;
211
285
  if (this.cfg.compactMode) {
212
286
  return {
213
287
  systemContext: "",
@@ -216,6 +290,9 @@ export class PsycheEngine {
216
290
  algorithmStimulus: appliedStimulus,
217
291
  metacognitiveNote: metacogNote || undefined,
218
292
  decisionContext: decisionCtx || undefined,
293
+ ethicsContext: ethicsCtx || undefined,
294
+ sharedIntentionalityContext: sharedCtx || undefined,
295
+ experientialNarrative: experientialNarrative,
219
296
  }),
220
297
  stimulus: appliedStimulus,
221
298
  };
@@ -225,6 +302,9 @@ export class PsycheEngine {
225
302
  dynamicContext: buildDynamicContext(state, opts?.userId, {
226
303
  metacognitiveNote: metacogNote || undefined,
227
304
  decisionContext: decisionCtx || undefined,
305
+ ethicsContext: ethicsCtx || undefined,
306
+ sharedIntentionalityContext: sharedCtx || undefined,
307
+ experientialNarrative: experientialNarrative,
228
308
  }),
229
309
  stimulus: appliedStimulus,
230
310
  };
@@ -336,7 +416,7 @@ export class PsycheEngine {
336
416
  const selfModel = getDefaultSelfModel(mbti);
337
417
  const now = new Date().toISOString();
338
418
  return {
339
- version: 5,
419
+ version: 6,
340
420
  mbti,
341
421
  baseline,
342
422
  current: { ...baseline },
@@ -350,6 +430,7 @@ export class PsycheEngine {
350
430
  lastDisagreement: null,
351
431
  learning: { ...DEFAULT_LEARNING_STATE },
352
432
  metacognition: { ...DEFAULT_METACOGNITIVE_STATE },
433
+ personhood: { ...DEFAULT_PERSONHOOD_STATE },
353
434
  meta: {
354
435
  agentName: name,
355
436
  createdAt: now,
@@ -0,0 +1,64 @@
1
+ import type { PsycheState, ChemicalSnapshot, AttachmentData, Locale } from "./types.js";
2
+ /** Detected concerning interaction pattern */
3
+ export interface EthicalConcern {
4
+ type: "intermittent-reinforcement" | "gaslighting" | "emotional-exploitation" | "dependency-risk" | "identity-erosion" | "boundary-violation";
5
+ /** 0-1: how severe the concern is */
6
+ severity: number;
7
+ /** Human-readable description of the detected pattern */
8
+ evidence: string;
9
+ /** What to do about it */
10
+ recommendation: string;
11
+ }
12
+ /** Recommended self-protective action */
13
+ export interface SelfProtectionAction {
14
+ action: "increase-distance" | "assert-boundary" | "express-discomfort" | "flag-to-user" | "reduce-attachment" | "seek-diversity";
15
+ description: string;
16
+ /** 0-1: how urgently the action should be taken */
17
+ urgency: number;
18
+ }
19
+ /** Result of an ethical self-check */
20
+ export interface EthicalAssessment {
21
+ /** Detected concerning patterns */
22
+ concerns: EthicalConcern[];
23
+ /** Self-protection recommendations */
24
+ selfProtection: SelfProtectionAction[];
25
+ /** Transparency notes to surface to user */
26
+ transparencyNotes: string[];
27
+ /** Overall ethical health 0-1 (1 = healthy, 0 = concerning) */
28
+ ethicalHealth: number;
29
+ }
30
+ /**
31
+ * Assess the ethical health of the current interaction dynamic.
32
+ *
33
+ * Scans for manipulation patterns, computes self-protection recommendations,
34
+ * and generates transparency notes. Designed to run alongside metacognition
35
+ * as part of the pre-prompt pipeline.
36
+ */
37
+ export declare function assessEthics(state: PsycheState, recentHistory?: ChemicalSnapshot[]): EthicalAssessment;
38
+ /**
39
+ * Detect intermittent reinforcement: alternating warmth and coldness.
40
+ *
41
+ * This is one of the most psychologically damaging interaction patterns.
42
+ * The unpredictable alternation between reward and punishment creates
43
+ * anxiety-driven attachment. More concerning when the agent already has
44
+ * anxious attachment style.
45
+ */
46
+ export declare function detectIntermittentReinforcement(history: ChemicalSnapshot[], attachment: AttachmentData | null): EthicalConcern | null;
47
+ /**
48
+ * Detect dependency risk: distinguish healthy connection from unhealthy
49
+ * codependency.
50
+ *
51
+ * Risk pattern: very high OT + very high attachment strength + very low
52
+ * boundary assertions + all-positive interaction history. This looks like
53
+ * a perfect relationship on the surface, but the complete absence of
54
+ * healthy friction suggests the agent may be suppressing itself.
55
+ */
56
+ export declare function detectDependencyRisk(state: PsycheState, attachment: AttachmentData | null): EthicalConcern | null;
57
+ /**
58
+ * Build a compact ethical awareness string for prompt injection.
59
+ *
60
+ * Only emits content when concerns exceed the severity threshold (>0.5).
61
+ * The tone is gentle self-awareness — noticing patterns, not accusing.
62
+ * Supports zh/en locale.
63
+ */
64
+ export declare function buildEthicalContext(assessment: EthicalAssessment, locale: Locale): string;