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/dist/circadian.js CHANGED
@@ -1,18 +1,6 @@
1
1
  // ============================================================
2
- // Artificial PsycheCircadian Rhythm Module
2
+ // Circadian Rhythmv11: modulates 4 self-state dimensions
3
3
  // ============================================================
4
- // Applies time-of-day modulation to virtual neurochemistry,
5
- // modeling the body's ~24-hour biological clock and fatigue
6
- // from extended sessions (homeostatic pressure).
7
- // ============================================================
8
- /**
9
- * Classify a time into a circadian phase.
10
- * morning: 6–9
11
- * midday: 10–13
12
- * afternoon: 14–17
13
- * evening: 18–21
14
- * night: 22–5
15
- */
16
4
  export function getCircadianPhase(time) {
17
5
  const h = time.getHours();
18
6
  if (h >= 6 && h <= 9)
@@ -26,47 +14,33 @@ export function getCircadianPhase(time) {
26
14
  return "night";
27
15
  }
28
16
  // ── Sinusoidal Helpers ───────────────────────────────────────
29
- /** Convert hour (0-23) + minute to fractional hours */
30
17
  function fractionalHour(time) {
31
18
  return time.getHours() + time.getMinutes() / 60;
32
19
  }
33
- /**
34
- * Sinusoidal modulation: amplitude * cos(2π(t - peak) / 24)
35
- * Returns value in [-amplitude, +amplitude], peaking at `peakHour`.
36
- */
37
20
  function sinMod(t, peakHour, amplitude) {
38
21
  const phase = ((t - peakHour) / 24) * 2 * Math.PI;
39
22
  return amplitude * Math.cos(phase);
40
23
  }
41
- // ── Circadian Modulation ─────────────────────────────────────
24
+ // ── Circadian Modulation (4D) ───────────────────────────────
42
25
  /**
43
- * Apply circadian rhythm modulation to baseline chemistry.
44
- *
45
- * Each chemical follows a sinusoidal daily curve:
46
- * CORT — peaks ~8am, amplitude ±8
47
- * HT — peaks ~13 (daytime high), amplitude ±5
48
- * DA — slight afternoon peak ~14, amplitude ±3
49
- * NE — morning rise ~10, amplitude ±5
50
- * END — evening rise ~20, amplitude ±3
51
- * OT — evening warmth ~20, amplitude ±2
26
+ * Apply circadian rhythm modulation to baseline self-state.
52
27
  *
53
- * All results clamped to [0, 100].
28
+ * order — peaks ~13 (midday coherence), amplitude ±5
29
+ * flow — peaks ~10 (morning engagement), amplitude ±5
30
+ * boundary — peaks ~8 (morning clarity), amplitude ±3
31
+ * resonance — peaks ~20 (evening warmth), amplitude ±3
54
32
  */
55
33
  export function computeCircadianModulation(currentTime, baseline) {
56
34
  const t = fractionalHour(currentTime);
57
- const cortDelta = sinMod(t, 8, 8);
58
- const htDelta = sinMod(t, 13, 5);
59
- const daDelta = sinMod(t, 14, 3);
60
- const neDelta = sinMod(t, 10, 5);
61
- const endDelta = sinMod(t, 20, 3);
62
- const otDelta = sinMod(t, 20, 2);
35
+ const orderDelta = sinMod(t, 13, 5);
36
+ const flowDelta = sinMod(t, 10, 5);
37
+ const boundaryDelta = sinMod(t, 8, 3);
38
+ const resonanceDelta = sinMod(t, 20, 3);
63
39
  return {
64
- DA: clamp(baseline.DA + daDelta),
65
- HT: clamp(baseline.HT + htDelta),
66
- CORT: clamp(baseline.CORT + cortDelta),
67
- OT: clamp(baseline.OT + otDelta),
68
- NE: clamp(baseline.NE + neDelta),
69
- END: clamp(baseline.END + endDelta),
40
+ order: clamp(baseline.order + orderDelta),
41
+ flow: clamp(baseline.flow + flowDelta),
42
+ boundary: clamp(baseline.boundary + boundaryDelta),
43
+ resonance: clamp(baseline.resonance + resonanceDelta),
70
44
  };
71
45
  }
72
46
  function clamp(v, lo = 0, hi = 100) {
@@ -75,30 +49,21 @@ function clamp(v, lo = 0, hi = 100) {
75
49
  // ── Homeostatic Pressure ─────────────────────────────────────
76
50
  /**
77
51
  * Compute fatigue effects from extended session duration.
78
- *
79
- * Below 30 minutes: no pressure (grace period).
80
- * Beyond 30 min: logarithmic growth (diminishing returns).
81
- * All values non-negative.
52
+ * Now expressed as dimension effects instead of chemical deltas.
82
53
  */
83
54
  export function computeHomeostaticPressure(sessionMinutes) {
84
55
  if (sessionMinutes < 30) {
85
- return { cortAccumulation: 0, daDepletion: 0, neDepletion: 0 };
56
+ return { orderDepletion: 0, flowDepletion: 0, boundaryStiffening: 0 };
86
57
  }
87
- // Effective minutes beyond the grace period
88
58
  const effective = sessionMinutes - 30;
89
- // Logarithmic growth diminishing returns
90
- // ln(1 + x) grows slowly; scale factors tuned so 1h ≈ moderate, 10h ≈ high but bounded
91
- const base = Math.log1p(effective / 30); // ln(1 + effective/30)
59
+ const base = Math.log1p(effective / 30);
92
60
  return {
93
- cortAccumulation: parseFloat((base * 4).toFixed(4)),
94
- daDepletion: parseFloat((base * 3).toFixed(4)),
95
- neDepletion: parseFloat((base * 2.5).toFixed(4)),
61
+ orderDepletion: parseFloat((base * 3.5).toFixed(4)),
62
+ flowDepletion: parseFloat((base * 3).toFixed(4)),
63
+ boundaryStiffening: parseFloat((base * 2).toFixed(4)),
96
64
  };
97
65
  }
98
- // ── Energy Budgets (v9) ─────────────────────────────────────
99
- // Finite cognitive/social resources that deplete during interaction.
100
- // Extraverts GAIN social energy from interaction; introverts LOSE it.
101
- /** Stimulus-specific attention costs (higher = more draining) */
66
+ // ── Energy Budgets (unchanged — substrate-independent) ──────
102
67
  const ATTENTION_COSTS = {
103
68
  intellectual: 5,
104
69
  conflict: 5,
@@ -108,7 +73,6 @@ const ATTENTION_COSTS = {
108
73
  criticism: 3,
109
74
  surprise: 2,
110
75
  };
111
- /** Stimulus-specific decision costs */
112
76
  const DECISION_COSTS = {
113
77
  conflict: 4,
114
78
  authority: 4,
@@ -116,46 +80,22 @@ const DECISION_COSTS = {
116
80
  criticism: 2,
117
81
  sarcasm: 2,
118
82
  };
119
- /**
120
- * Deplete energy budgets from a single interaction turn.
121
- *
122
- * - Attention: -3/turn base, extra for intellectual/conflict
123
- * - Social energy: extraverts +2/turn (charging), introverts -3/turn (draining)
124
- * - Decision capacity: varies by stimulus complexity
125
- *
126
- * Extraverts can exceed 100 (up to 120 — "supercharged").
127
- */
128
83
  export function computeEnergyDepletion(budgets, stimulus, isExtravert) {
129
- const extravertMax = 120;
130
- const introvertMax = 100;
131
- const max = isExtravert ? extravertMax : introvertMax;
132
- // Attention: base -3, extra from stimulus
84
+ const max = isExtravert ? 120 : 100;
133
85
  const attentionCost = 3 + (stimulus ? (ATTENTION_COSTS[stimulus] ?? 0) : 0);
134
86
  const attention = clamp(budgets.attention - attentionCost, 0, 100);
135
- // Social energy: E charges, I drains
136
87
  const socialDelta = isExtravert ? 2 : -3;
137
88
  const socialEnergy = clamp(budgets.socialEnergy + socialDelta, 0, max);
138
- // Decision capacity: base -1, extra from stimulus
139
89
  const decisionCost = 1 + (stimulus ? (DECISION_COSTS[stimulus] ?? 0) : 0);
140
90
  const decisionCapacity = clamp(budgets.decisionCapacity - decisionCost, 0, 100);
141
91
  return { attention, socialEnergy, decisionCapacity };
142
92
  }
143
- /**
144
- * Recover energy budgets during absence (between sessions or long pauses).
145
- *
146
- * - Attention: +20/hour
147
- * - Social energy: extraverts -3/hour (drain when alone), introverts +15/hour (recharge)
148
- * - Decision capacity: +25/hour
149
- */
150
93
  export function computeEnergyRecovery(budgets, minutesElapsed, isExtravert) {
151
94
  if (minutesElapsed <= 0)
152
95
  return { ...budgets };
153
96
  const hours = minutesElapsed / 60;
154
- const extravertMax = 120;
155
- const introvertMax = 100;
156
- const max = isExtravert ? extravertMax : introvertMax;
97
+ const max = isExtravert ? 120 : 100;
157
98
  const attention = clamp(budgets.attention + hours * 20, 0, 100);
158
- // E drains alone, I recharges alone
159
99
  const socialDelta = isExtravert ? -3 * hours : 15 * hours;
160
100
  const socialEnergy = clamp(budgets.socialEnergy + socialDelta, 0, max);
161
101
  const decisionCapacity = clamp(budgets.decisionCapacity + hours * 25, 0, 100);
package/dist/cli.js CHANGED
@@ -16,6 +16,7 @@
16
16
  // psyche probe [--json]
17
17
  // psyche profiles [--json] [--mbti TYPE]
18
18
  // psyche setup [--name NAME] [--mbti TYPE] [--locale LOCALE] [--proxy --target URL] [--dry-run]
19
+ // psyche mcp [--mbti TYPE] [--name NAME] Start MCP server (stdio)
19
20
  // ============================================================
20
21
  import { resolve, join } from "node:path";
21
22
  import { homedir } from "node:os";
@@ -27,8 +28,8 @@ import { generateReport, formatReport, toGitHubIssueBody } from "./diagnostics.j
27
28
  import { getBaseline, getTemperament, getSensitivity, getDefaultSelfModel, traitsToBaseline } from "./profiles.js";
28
29
  import { buildDynamicContext, buildProtocolContext } from "./prompt.js";
29
30
  import { t } from "./i18n.js";
30
- import { CHEMICAL_KEYS, CHEMICAL_NAMES_ZH, DRIVE_KEYS, DRIVE_NAMES_ZH } from "./types.js";
31
- import { isMBTIType, isChemicalKey, isLocale } from "./guards.js";
31
+ import { DIMENSION_KEYS, DIMENSION_NAMES_ZH, DRIVE_KEYS, DRIVE_NAMES_ZH } from "./types.js";
32
+ import { isMBTIType, isDimensionKey, isLocale } from "./guards.js";
32
33
  import { getPackageVersion, selfUpdate } from "./update.js";
33
34
  import { runRuntimeProbe } from "./runtime-probe.js";
34
35
  // ── Logger ───────────────────────────────────────────────────
@@ -50,14 +51,14 @@ function arrow(current, baseline) {
50
51
  return "\u2193";
51
52
  return "=";
52
53
  }
53
- function printChemistry(state) {
54
+ function printState(state) {
54
55
  const { current, baseline } = state;
55
- for (const key of CHEMICAL_KEYS) {
56
+ for (const key of DIMENSION_KEYS) {
56
57
  const val = Math.round(current[key]);
57
58
  const base = baseline[key];
58
59
  const a = arrow(val, base);
59
- const label = `${key}`.padEnd(4);
60
- const nameZh = CHEMICAL_NAMES_ZH[key].padEnd(6);
60
+ const label = `${key}`.padEnd(10);
61
+ const nameZh = DIMENSION_NAMES_ZH[key].padEnd(4);
61
62
  console.log(` ${label} ${nameZh} ${bar(val)} ${String(val).padStart(3)} (base:${base} ${a})`);
62
63
  }
63
64
  }
@@ -143,7 +144,7 @@ async function cmdInit(dir, mbti, name, lang, mode, traits, _noPersist) {
143
144
  await saveState(absDir, state);
144
145
  }
145
146
  console.log(`\nPsyche initialized for ${state.meta.agentName}${state.mbti ? ` (preset: ${state.mbti})` : ""}\n`);
146
- printChemistry(state);
147
+ printState(state);
147
148
  console.log(`\nFiles created:`);
148
149
  console.log(` ${absDir}/psyche-state.json`);
149
150
  console.log(` ${absDir}/PSYCHE.md`);
@@ -168,12 +169,12 @@ async function cmdStatus(dir, json, userId) {
168
169
  const hint = getExpressionHint(state.current, locale);
169
170
  const elapsed = ((Date.now() - new Date(state.updatedAt).getTime()) / 60000).toFixed(1);
170
171
  const baselineSummary = [
171
- state.baseline.DA < 55 ? "introvert" : "extrovert",
172
- state.baseline.DA > state.baseline.HT ? "intuitive" : "sensing",
173
- state.baseline.OT >= 50 ? "feeling" : "thinking",
172
+ state.baseline.flow < 55 ? "introvert" : "extrovert",
173
+ state.baseline.flow > state.baseline.order ? "intuitive" : "sensing",
174
+ state.baseline.resonance >= 50 ? "feeling" : "thinking",
174
175
  ].join("/");
175
176
  console.log(`\n${state.meta.agentName} (${baselineSummary}) — ${emotion}\n`);
176
- printChemistry(state);
177
+ printState(state);
177
178
  console.log();
178
179
  printDrives(state);
179
180
  printEmotions(state);
@@ -224,7 +225,7 @@ async function cmdDecay(dir) {
224
225
  const after = await decayAndSave(absDir, before);
225
226
  const elapsed = ((Date.now() - new Date(before.updatedAt).getTime()) / 60000).toFixed(1);
226
227
  console.log(`\nDecay applied (${elapsed} min elapsed)\n`);
227
- for (const key of CHEMICAL_KEYS) {
228
+ for (const key of DIMENSION_KEYS) {
228
229
  const bVal = Math.round(before.current[key]);
229
230
  const aVal = Math.round(after.current[key]);
230
231
  if (bVal !== aVal) {
@@ -245,15 +246,15 @@ async function cmdUpdate(dir, updateJson, userId) {
245
246
  }
246
247
  // Validate keys using type guard
247
248
  for (const key of Object.keys(parsed)) {
248
- if (!isChemicalKey(key)) {
249
- die(`unknown chemical key: ${key}. Valid: ${CHEMICAL_KEYS.join(", ")}`);
249
+ if (!isDimensionKey(key)) {
250
+ die(`unknown dimension key: ${key}. Valid: ${DIMENSION_KEYS.join(", ")}`);
250
251
  }
251
252
  }
252
253
  const updates = { current: parsed };
253
254
  const merged = mergeUpdates(state, updates, 25, userId);
254
255
  await saveState(absDir, merged);
255
- console.log(`\nChemistry updated for ${merged.meta.agentName}\n`);
256
- printChemistry(merged);
256
+ console.log(`\nState updated for ${merged.meta.agentName}\n`);
257
+ printState(merged);
257
258
  console.log();
258
259
  }
259
260
  async function cmdReset(dir, full) {
@@ -265,14 +266,14 @@ async function cmdReset(dir, full) {
265
266
  state.empathyLog = null;
266
267
  state.agreementStreak = 0;
267
268
  state.lastDisagreement = null;
268
- state.emotionalHistory = [];
269
+ state.stateHistory = [];
269
270
  if (full) {
270
271
  state.relationships = { _default: { trust: 50, intimacy: 30, phase: "acquaintance" } };
271
272
  }
272
273
  await saveState(absDir, state);
273
274
  await generatePsycheMd(absDir, state);
274
275
  console.log(`\n${state.meta.agentName} reset to baseline${full ? " [full reset including relationships]" : ""}\n`);
275
- printChemistry(state);
276
+ printState(state);
276
277
  console.log();
277
278
  }
278
279
  function cmdProfiles(json, mbti) {
@@ -291,10 +292,10 @@ function cmdProfiles(json, mbti) {
291
292
  }
292
293
  console.log(`\n${upper} — ${temperament}\n`);
293
294
  console.log(` Sensitivity: ${sensitivity}`);
294
- for (const key of CHEMICAL_KEYS) {
295
+ for (const key of DIMENSION_KEYS) {
295
296
  const val = baseline[key];
296
- const label = `${key}`.padEnd(4);
297
- const nameZh = CHEMICAL_NAMES_ZH[key].padEnd(6);
297
+ const label = `${key}`.padEnd(10);
298
+ const nameZh = DIMENSION_NAMES_ZH[key].padEnd(4);
298
299
  console.log(` ${label} ${nameZh} ${bar(val)} ${val}`);
299
300
  }
300
301
  console.log(`\n Values: ${selfModel.values.join(", ")}`);
@@ -333,9 +334,8 @@ function cmdProfiles(json, mbti) {
333
334
  const bl = getBaseline(mbtiType);
334
335
  const temperament = getTemperament(mbtiType);
335
336
  const sens = getSensitivity(mbtiType);
336
- console.log(` ${t} DA:${String(bl.DA).padStart(2)} HT:${String(bl.HT).padStart(2)} ` +
337
- `CORT:${String(bl.CORT).padStart(2)} OT:${String(bl.OT).padStart(2)} ` +
338
- `NE:${String(bl.NE).padStart(2)} END:${String(bl.END).padStart(2)} ` +
337
+ console.log(` ${t} order:${String(bl.order).padStart(2)} flow:${String(bl.flow).padStart(2)} ` +
338
+ `boundary:${String(bl.boundary).padStart(2)} resonance:${String(bl.resonance).padStart(2)} ` +
339
339
  `sens:${sens} ${temperament.slice(0, 30)}...`);
340
340
  }
341
341
  console.log();
@@ -521,7 +521,7 @@ async function cmdSetup(opts) {
521
521
  env.PSYCHE_LOCALE = locale;
522
522
  let actions = 0;
523
523
  // ── 1. MCP clients ────────────────────────────────────
524
- const mcpEntry = { command: "npx", args: ["-y", "psyche-mcp"], env };
524
+ const mcpEntry = { command: "npx", args: ["-y", "psyche-ai", "mcp"], env };
525
525
  const { execFileSync } = await import("node:child_process");
526
526
  // Claude Code — use `claude mcp add` for hot-reload (no restart needed)
527
527
  let claudeCodeDone = false;
@@ -537,12 +537,12 @@ async function cmdSetup(opts) {
537
537
  actions++;
538
538
  }
539
539
  else {
540
- const addArgs = ["mcp", "add", "psyche", "-e", "PSYCHE_LOCALE=" + (locale || "zh")];
540
+ const addArgs = ["mcp", "add", "-s", "user", "psyche", "-e", "PSYCHE_LOCALE=" + (locale || "zh")];
541
541
  if (name)
542
542
  addArgs.push("-e", "PSYCHE_NAME=" + name);
543
543
  if (mbti)
544
544
  addArgs.push("-e", "PSYCHE_MBTI=" + mbti.toUpperCase());
545
- addArgs.push("--", "npx", "-y", "psyche-mcp");
545
+ addArgs.push("--", "npx", "-y", "psyche-ai", "mcp");
546
546
  execFileSync("claude", addArgs, { encoding: "utf-8", timeout: 10000 });
547
547
  console.log(" ✓ Claude Code — configured (live, no restart needed)");
548
548
  claudeCodeDone = true;
@@ -651,6 +651,7 @@ Usage:
651
651
  psyche intensity Show info about personality intensity config
652
652
  psyche reset <dir> [--full]
653
653
  psyche diagnose <dir> [--github] Run health checks & show diagnostic report
654
+ psyche mcp [--mbti TYPE] [--name NAME] Start MCP server (stdio)
654
655
  psyche setup [--proxy -t URL] [-n NAME] [--mbti TYPE] Auto-configure MCP + proxy
655
656
  psyche upgrade [--check] Check/apply package updates safely
656
657
  psyche probe [--json] Verify the runtime is truly callable
@@ -684,11 +685,12 @@ Examples:
684
685
  psyche profiles
685
686
  psyche profiles --mbti ENFP
686
687
 
687
- # Auto-configure all MCP clients
688
- psyche setup --mbti ENFP --name Luna
688
+ # Auto-configure all MCP clients (one command, done)
689
+ psyche setup
690
+ psyche setup --name Luna
689
691
 
690
692
  # Universal proxy — works with any agent using OpenAI SDK
691
- psyche setup --proxy -t https://api.openai.com/v1 --mbti ENFP
693
+ psyche setup --proxy -t https://api.openai.com/v1
692
694
 
693
695
  # Check for new package versions without applying them
694
696
  psyche upgrade --check
@@ -846,6 +848,11 @@ async function main() {
846
848
  await cmdProbe(values.json ?? false);
847
849
  break;
848
850
  }
851
+ case "mcp": {
852
+ // Delegate to the MCP adapter — same process, no npx indirection.
853
+ await import("./adapters/mcp.js");
854
+ return; // mcp.ts owns the process from here
855
+ }
849
856
  case "setup": {
850
857
  const { values } = parseArgs({
851
858
  args: rest,
@@ -25,8 +25,8 @@ export function extractContextFeatures(state, userId) {
25
25
  const relKey = userId ?? "_default";
26
26
  const relationship = state.relationships[relKey] ?? state.relationships["_default"];
27
27
  const relationshipPhase = relationship?.phase ?? "stranger";
28
- // Recent stimuli from emotional history (last 3)
29
- const recentStimuli = state.emotionalHistory
28
+ // Recent stimuli from state history (last 3)
29
+ const recentStimuli = state.stateHistory
30
30
  .slice(-3)
31
31
  .map((snap) => snap.stimulus)
32
32
  .filter((s) => s !== null);
package/dist/core.d.ts CHANGED
@@ -8,7 +8,7 @@ export interface PsycheEngineConfig {
8
8
  locale?: Locale;
9
9
  stripUpdateTags?: boolean;
10
10
  emotionalContagionRate?: number;
11
- maxChemicalDelta?: number;
11
+ maxDimensionDelta?: number;
12
12
  /** @deprecated Compact mode is always on since v10. This option is ignored. */
13
13
  compactMode?: boolean;
14
14
  /** Operating mode: "natural" (default), "work" (minimal emotions), "companion" (full emotions) */
@@ -77,7 +77,7 @@ export interface ProcessInputResult {
77
77
  export interface ProcessOutputResult {
78
78
  /** LLM output with <psyche_update> tags stripped */
79
79
  cleanedText: string;
80
- /** Whether chemistry was meaningfully updated (contagion or psyche_update) */
80
+ /** Whether self-state was meaningfully updated (contagion or psyche_update) */
81
81
  stateChanged: boolean;
82
82
  }
83
83
  export interface ProcessOutputOptions {
@@ -150,7 +150,7 @@ export declare class PsycheEngine {
150
150
  */
151
151
  getProtocol(locale?: Locale): string;
152
152
  /**
153
- * End the current session: compress emotionalHistory into a rich summary
153
+ * End the current session: compress stateHistory into a rich summary
154
154
  * stored in relationship.memory[], then preserve only core/recent context.
155
155
  * Auto-generates diagnostic report and persists to log.
156
156
  *