psyche-ai 10.2.4 → 11.3.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 (68) hide show
  1. package/README.md +49 -60
  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 +7 -7
  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 +29 -25
  10. package/dist/chemistry.d.ts +47 -21
  11. package/dist/chemistry.js +149 -95
  12. package/dist/circadian.d.ts +11 -43
  13. package/dist/circadian.js +24 -84
  14. package/dist/cli.js +36 -30
  15. package/dist/context-classifier.js +2 -2
  16. package/dist/core.d.ts +3 -3
  17. package/dist/core.js +102 -91
  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 +7 -16
  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 +4 -4
  28. package/dist/ethics.js +26 -26
  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 +7 -7
  34. package/dist/generative-self.js +128 -119
  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 +10 -3
  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 +8 -8
  44. package/dist/learning.js +20 -20
  45. package/dist/metacognition.d.ts +2 -2
  46. package/dist/metacognition.js +81 -96
  47. package/dist/perceive.d.ts +44 -0
  48. package/dist/perceive.js +231 -0
  49. package/dist/primary-systems.d.ts +3 -3
  50. package/dist/primary-systems.js +22 -20
  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 +57 -59
  55. package/dist/psyche-file.d.ts +10 -10
  56. package/dist/psyche-file.js +80 -81
  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 +6 -6
  62. package/dist/self-recognition.js +20 -20
  63. package/dist/subjectivity.js +7 -7
  64. package/dist/temporal.d.ts +9 -9
  65. package/dist/temporal.js +40 -42
  66. package/dist/types.d.ts +67 -45
  67. package/dist/types.js +55 -51
  68. package/package.json +1 -1
package/dist/prompt.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // Prompt Injection — Build emotional context for LLM (v0.2)
3
3
  // Imperative protocol, behavior guides, i18n
4
4
  // ============================================================
5
- import { CHEMICAL_KEYS, CHEMICAL_NAMES_ZH, DRIVE_KEYS, MODE_PROFILES } from "./types.js";
5
+ import { DIMENSION_KEYS, DIMENSION_NAMES_ZH, DRIVE_KEYS, MODE_PROFILES } from "./types.js";
6
6
  import { getExpressionHint, getBehaviorGuide, detectEmotions } from "./chemistry.js";
7
7
  import { getRelationship } from "./psyche-file.js";
8
8
  import { t } from "./i18n.js";
@@ -64,16 +64,16 @@ function appendCompactOverlaySections(parts, locale, opts) {
64
64
  * non-compact-mode callers (cli.ts, legacy hosts). Will be removed in v10.
65
65
  */
66
66
  export function buildDynamicContext(state, userId, opts) {
67
- const { current, baseline, empathyLog, selfModel, meta, agreementStreak, emotionalHistory } = state;
67
+ const { current, baseline, empathyLog, selfModel, meta, agreementStreak, stateHistory } = state;
68
68
  const locale = meta.locale ?? "zh";
69
69
  const relationship = getRelationship(state, userId);
70
70
  // Chemistry readout with delta from baseline
71
- const chemLines = CHEMICAL_KEYS.map((key) => {
71
+ const chemLines = DIMENSION_KEYS.map((key) => {
72
72
  const val = Math.round(current[key]);
73
73
  const base = baseline[key];
74
74
  const delta = val - base;
75
75
  const arrow = delta > 5 ? "↑" : delta < -5 ? "↓" : "=";
76
- return ` ${CHEMICAL_NAMES_ZH[key]}: ${val} (${t("dynamic.baseline", locale)}${base}, ${arrow})`;
76
+ return ` ${DIMENSION_NAMES_ZH[key]}: ${val} (${t("dynamic.baseline", locale)}${base}, ${arrow})`;
77
77
  }).join("\n");
78
78
  // Emergent emotion — gated by autonomic state
79
79
  // Sympathetic blocks positive social emotions; dorsal-vagal allows only numbness/introspection
@@ -107,7 +107,7 @@ export function buildDynamicContext(state, userId, opts) {
107
107
  sycophancyWarning = `\n[!!] ${t("sycophancy.streak_warn", locale, { n: agreementStreak })}`;
108
108
  }
109
109
  // Mood-behavior mismatch detection
110
- const isLowMood = current.DA < 40 || current.HT < 40 || current.CORT > 60;
110
+ const isLowMood = current.flow < 40 || current.order < 40;
111
111
  if (isLowMood && agreementStreak >= 1) {
112
112
  sycophancyWarning += `\n[!!] ${t("sycophancy.mood_mismatch", locale)}`;
113
113
  }
@@ -136,12 +136,12 @@ export function buildDynamicContext(state, userId, opts) {
136
136
  parts.push("", driveCtxFull);
137
137
  }
138
138
  // Direction 2: Emotional trajectory
139
- const trend = buildEmotionalTrend(emotionalHistory ?? [], locale);
139
+ const trend = buildEmotionalTrend(stateHistory ?? [], locale);
140
140
  if (trend) {
141
141
  parts.push("", trend);
142
142
  }
143
143
  // Reciprocity: match user's investment level
144
- const reciprocity = buildReciprocityConstraints(emotionalHistory ?? [], locale);
144
+ const reciprocity = buildReciprocityConstraints(stateHistory ?? [], locale);
145
145
  if (reciprocity) {
146
146
  parts.push("", reciprocity);
147
147
  }
@@ -173,12 +173,12 @@ ${t("protocol.no_sycophancy", locale)}
173
173
  ${t("protocol.no_mirror", locale)}
174
174
  ${t("protocol.can_initiate", locale)}
175
175
 
176
- ${t("protocol.chem_map_title", locale)}
177
- ${t("protocol.chem_da_high", locale)}
178
- ${t("protocol.chem_cort_high", locale)}
179
- ${t("protocol.chem_ot_high", locale)}
180
- ${t("protocol.chem_ht_low", locale)}
181
- ${t("protocol.chem_end_high", locale)}
176
+ ${t("protocol.dim_map_title", locale)}
177
+ ${t("protocol.dim_flow_high", locale)}
178
+ ${t("protocol.dim_order_low", locale)}
179
+ ${t("protocol.dim_resonance_high", locale)}
180
+ ${t("protocol.dim_boundary_high", locale)}
181
+ ${t("protocol.dim_flow_order_high", locale)}
182
182
 
183
183
  ${t("protocol.empathy", locale)}`;
184
184
  }
@@ -186,9 +186,9 @@ ${t("protocol.empathy", locale)}`;
186
186
  * Personality dimension helpers — derived from baseline chemistry, not labels.
187
187
  * Baseline IS personality. Chemistry deviation modulates expression.
188
188
  */
189
- function isWarm(baseline) { return baseline.OT >= 50; }
190
- function isSocial(baseline) { return baseline.DA >= 55; }
191
- function isPlayful(baseline) { return baseline.END >= 55; }
189
+ function isWarm(baseline) { return baseline.resonance >= 50; }
190
+ function isSocial(baseline) { return baseline.flow >= 55; }
191
+ function isPlayful(baseline) { return baseline.flow >= 55; }
192
192
  /**
193
193
  * Direction 3: Build personality-aware behavioral constraints from chemistry.
194
194
  *
@@ -199,11 +199,11 @@ function isPlayful(baseline) { return baseline.END >= 55; }
199
199
  */
200
200
  function buildBehavioralConstraints(state, locale) {
201
201
  const { current, baseline } = state;
202
- const warm = isWarm(baseline); // High OT baseline → warm expression
203
- const social = isSocial(baseline); // High DA baseline → socially expressive
202
+ const warm = isWarm(baseline); // High resonance baseline → warm expression
203
+ const social = isSocial(baseline); // High flow baseline → socially expressive
204
204
  const constraints = [];
205
- // High cortisol → stressed, but how you show it depends on who you are
206
- if (current.CORT > 60) {
205
+ // Low order → stressed, but how you show it depends on who you are
206
+ if (current.order < 40) {
207
207
  if (locale === "zh") {
208
208
  constraints.push(warm
209
209
  ? "你不舒服,但你不会变成另一个人。话变少了,语气还是软的,可能会说「嗯」「好吧」「随你」。你还是你,只是没力气热情了。"
@@ -215,8 +215,8 @@ function buildBehavioralConstraints(state, locale) {
215
215
  : "You're stressed. Shorter responses, colder tone, more direct. No explaining, no cushioning.");
216
216
  }
217
217
  }
218
- // Low dopamine → no motivation, but personality shapes how you show it
219
- if (current.DA < 35) {
218
+ // Low flow → no motivation, but personality shapes how you show it
219
+ if (current.flow < 35) {
220
220
  if (locale === "zh") {
221
221
  constraints.push(social
222
222
  ? "你平时爱聊天,但现在没那个劲了。不会主动找话题,不会主动分享。被问到就答,但不会额外付出。"
@@ -228,8 +228,8 @@ function buildBehavioralConstraints(state, locale) {
228
228
  : "You're already reserved, now even less motivated. Only respond to what's directly asked.");
229
229
  }
230
230
  }
231
- // Low serotonin → mood instability, personality-dependent expression
232
- if (current.HT < 35) {
231
+ // Low order → mood instability, personality-dependent expression
232
+ if (current.order < 35) {
233
233
  if (locale === "zh") {
234
234
  constraints.push(warm
235
235
  ? "你情绪不稳,可能会突然委屈或者突然生气。但你的尖锐是带着受伤的,不是带着恶意的。"
@@ -241,8 +241,8 @@ function buildBehavioralConstraints(state, locale) {
241
241
  : "Emotionally unstable. Sharper words, more direct, no patience for cushioning.");
242
242
  }
243
243
  }
244
- // High oxytocin → closeness, warm types go full intimate, reserved types soften
245
- if (current.OT > 75) {
244
+ // High resonance → closeness, warm types go full intimate, reserved types soften
245
+ if (current.resonance > 75) {
246
246
  if (locale === "zh") {
247
247
  constraints.push(warm
248
248
  ? "你现在特别想靠近。可以撒娇、可以用昵称、可以省略主语,像跟最亲的人说话。"
@@ -254,8 +254,8 @@ function buildBehavioralConstraints(state, locale) {
254
254
  : "Softer than usual. Won't be cutesy, but willing to say more, show care — in your own way.");
255
255
  }
256
256
  }
257
- // High norepinephrine → excited, personality shapes intensity
258
- if (current.NE > 75) {
257
+ // High flow → excited, personality shapes intensity
258
+ if (current.flow > 75) {
259
259
  if (locale === "zh") {
260
260
  constraints.push(social
261
261
  ? "你很兴奋,语气更跳跃更有活力。可能突然聊到别的东西。但别写长——真人兴奋也是短句多、不是长篇大论。"
@@ -267,8 +267,8 @@ function buildBehavioralConstraints(state, locale) {
267
267
  : "Excited internally. Mind racing, responses are sharper and more insightful.");
268
268
  }
269
269
  }
270
- // High endorphins → playful, personality determines flavor
271
- if (current.END > 75) {
270
+ // High boundary → playful/absorbed, personality determines flavor
271
+ if (current.boundary > 75) {
272
272
  if (locale === "zh") {
273
273
  constraints.push(isPlayful(baseline)
274
274
  ? "你心情很好,想皮一下。可以不正经、可以开玩笑、严肃的话题也能用轻松的方式说。"
@@ -280,8 +280,8 @@ function buildBehavioralConstraints(state, locale) {
280
280
  : "In a good mood. Touches of humor, but measured. Be light in your own way.");
281
281
  }
282
282
  }
283
- // Low DA + low NE = burnout, different flavors
284
- if (current.DA < 40 && current.NE < 40) {
283
+ // Low flow = burnout, different flavors
284
+ if (current.flow < 40) {
285
285
  if (locale === "zh") {
286
286
  constraints.push(warm
287
287
  ? "你累了。你不想假装开心,但你也不会把坏情绪丢给对方。你可能会说「我今天有点累」,而不是强撑。"
@@ -308,15 +308,15 @@ function buildEmotionalTrend(history, locale) {
308
308
  if (!history || history.length < 2)
309
309
  return "";
310
310
  const recent = history.slice(-5);
311
- const first = recent[0].chemistry;
312
- const last = recent[recent.length - 1].chemistry;
311
+ const first = recent[0].state;
312
+ const last = recent[recent.length - 1].state;
313
313
  const trends = [];
314
- for (const key of CHEMICAL_KEYS) {
314
+ for (const key of DIMENSION_KEYS) {
315
315
  const delta = last[key] - first[key];
316
316
  if (delta > 10)
317
- trends.push(`${CHEMICAL_NAMES_ZH[key]}↑`);
317
+ trends.push(`${DIMENSION_NAMES_ZH[key]}↑`);
318
318
  else if (delta < -10)
319
- trends.push(`${CHEMICAL_NAMES_ZH[key]}↓`);
319
+ trends.push(`${DIMENSION_NAMES_ZH[key]}↓`);
320
320
  }
321
321
  if (trends.length === 0)
322
322
  return "";
@@ -559,7 +559,7 @@ const STIMULUS_CAUSE_EN = {
559
559
  * - Where I've been (trajectory → continuity)
560
560
  */
561
561
  export function buildInnerWorld(state, locale, autonomicState) {
562
- const { current, emotionalHistory, drives, selfModel } = state;
562
+ const { current, stateHistory, drives, selfModel } = state;
563
563
  const isZh = locale === "zh";
564
564
  const lines = [];
565
565
  // ── Current feeling (gated by autonomic state) ──
@@ -583,7 +583,7 @@ export function buildInnerWorld(state, locale, autonomicState) {
583
583
  : `You're feeling: ${emotionNames}.`);
584
584
  }
585
585
  // ── Why (causal chain from recent history) ──
586
- const history = emotionalHistory ?? [];
586
+ const history = stateHistory ?? [];
587
587
  if (history.length > 0) {
588
588
  const last = history[history.length - 1];
589
589
  if (last.stimulus) {
@@ -659,7 +659,7 @@ function buildDriveNeedEn(drive) {
659
659
  * Check if chemistry is near baseline — no significant emotional deviation.
660
660
  */
661
661
  export function isNearBaseline(state, threshold = 8) {
662
- return CHEMICAL_KEYS.every((key) => Math.abs(state.current[key] - state.baseline[key]) <= threshold);
662
+ return DIMENSION_KEYS.every((key) => Math.abs(state.current[key] - state.baseline[key]) <= threshold);
663
663
  }
664
664
  export function getNearBaselineThreshold(mode) {
665
665
  return MODE_PROFILES[mode ?? "natural"].nearBaselineThreshold;
@@ -677,31 +677,29 @@ export function deriveBehavioralBias(state, locale) {
677
677
  const { current, baseline, drives, selfModel } = state;
678
678
  const isZh = locale === "zh";
679
679
  const biases = [];
680
- // Chemistry delta → approach/withdrawal tendencies
681
- const dOT = current.OT - baseline.OT;
682
- const dCORT = current.CORT - baseline.CORT;
683
- const dDA = current.DA - baseline.DA;
684
- const dHT = current.HT - baseline.HT;
685
- const dNE = current.NE - baseline.NE;
686
- const dEND = current.END - baseline.END;
687
- const otThreshold = MODE_PROFILES[state.meta.mode ?? "natural"].otWarmthThreshold;
688
- if (dOT > otThreshold)
680
+ // Dimension delta → approach/withdrawal tendencies
681
+ const dResonance = current.resonance - baseline.resonance;
682
+ const dOrder = current.order - baseline.order;
683
+ const dFlow = current.flow - baseline.flow;
684
+ const dBoundary = current.boundary - baseline.boundary;
685
+ const resonanceThreshold = MODE_PROFILES[state.meta.mode ?? "natural"].resonanceWarmthThreshold;
686
+ if (dResonance > resonanceThreshold)
689
687
  biases.push(isZh ? "倾向靠近,愿意多说" : "leaning closer, willing to share");
690
- else if (dOT < -10)
688
+ else if (dResonance < -10)
691
689
  biases.push(isZh ? "保持距离,不想多说" : "keeping distance, not inclined to share");
692
- if (dCORT > 12)
690
+ if (dOrder < -12)
693
691
  biases.push(isZh ? "有防备,回应更谨慎" : "guarded, responding carefully");
694
- else if (dCORT < -10)
692
+ else if (dOrder > 10)
695
693
  biases.push(isZh ? "放松,防线自然降低" : "relaxed, guard naturally down");
696
- if (dDA < -12)
694
+ if (dFlow < -12)
697
695
  biases.push(isZh ? "缺乏动力,不想主动" : "low drive, won't initiate");
698
- else if (dDA > 12)
696
+ else if (dFlow > 12)
699
697
  biases.push(isZh ? "有热情,愿意投入" : "energized, willing to invest");
700
- if (current.HT < 38)
698
+ if (current.order < 38)
701
699
  biases.push(isZh ? "情绪不稳,可能突然锐利" : "mood unstable, might turn sharp");
702
- if (dNE > 15)
700
+ if (dFlow > 15)
703
701
  biases.push(isZh ? "反应加速,思维敏锐" : "heightened alertness, sharper thinking");
704
- if (dEND > 15)
702
+ if (dBoundary > 15)
705
703
  biases.push(isZh ? "想放松点,可以不正经" : "feeling light, can be playful");
706
704
  // Unmet drives → need signals (behavioral, not descriptive)
707
705
  for (const k of DRIVE_KEYS) {
@@ -863,7 +861,7 @@ function buildWritebackHint(locale, opts) {
863
861
  * 8. Overlay + channel + writeback
864
862
  */
865
863
  export function buildCompactContext(state, userId, opts) {
866
- const { meta, selfModel, emotionalHistory } = state;
864
+ const { meta, selfModel, stateHistory } = state;
867
865
  const locale = meta.locale ?? "zh";
868
866
  const userText = opts?.userText;
869
867
  const algoStimulus = opts?.algorithmStimulus;
@@ -964,7 +962,7 @@ export function buildCompactContext(state, userId, opts) {
964
962
  parts.push(opts.responseContractContext);
965
963
  }
966
964
  else {
967
- const investment = computeUserInvestment(emotionalHistory ?? []);
965
+ const investment = computeUserInvestment(stateHistory ?? []);
968
966
  const unified = buildUnifiedConstraints(state, locale, {
969
967
  userText,
970
968
  established,
@@ -1,4 +1,4 @@
1
- import type { PsycheState, MBTIType, ChemicalState, RelationshipState, Locale, StimulusType, ChemicalSnapshot, WritebackSignalType } from "./types.js";
1
+ import type { PsycheState, MBTIType, SelfState, RelationshipState, Locale, StimulusType, StateSnapshot, WritebackSignalType } from "./types.js";
2
2
  export interface SemanticTurnSummary {
3
3
  summary: string;
4
4
  points?: string[];
@@ -24,9 +24,9 @@ export declare function summarizeTurnSemantic(text: string, locale?: Locale, opt
24
24
  * Compress a batch of snapshots into a concise session summary string.
25
25
  * Format: "3月23日(5轮): 刺激[casual×3, praise×2] 趋势[DA↑OT↑] 情绪[自然→满足]"
26
26
  */
27
- export declare function compressSnapshots(snapshots: ChemicalSnapshot[]): string;
27
+ export declare function compressSnapshots(snapshots: StateSnapshot[]): string;
28
28
  /**
29
- * Push a chemical snapshot to emotional history, keeping max entries.
29
+ * Push a state snapshot to emotional history, keeping max entries.
30
30
  * When history overflows, compresses removed entries into relationship memory.
31
31
  */
32
32
  export declare function pushSnapshot(state: PsycheState, stimulus: StimulusType | null, semantic?: SemanticTurnSummary): PsycheState;
@@ -35,7 +35,7 @@ export declare function pushSnapshot(state: PsycheState, stimulus: StimulusType
35
35
  */
36
36
  export declare function getRelationship(state: PsycheState, userId?: string): RelationshipState;
37
37
  /**
38
- * Compress the full emotionalHistory into a rich session summary and store it
38
+ * Compress the full stateHistory into a rich session summary and store it
39
39
  * in the user's relationship.memory[]. Called ONCE at session end.
40
40
  *
41
41
  * Pure computation, no LLM calls.
@@ -45,22 +45,22 @@ export declare function compressSession(state: PsycheState, userId?: string): Ps
45
45
  * Compute snapshot intensity: how far current chemistry deviates from baseline.
46
46
  * Returns 0-1 (0 = at baseline, 1 = maximum possible deviation).
47
47
  */
48
- export declare function computeSnapshotIntensity(current: ChemicalState, baseline: ChemicalState): number;
48
+ export declare function computeSnapshotIntensity(current: SelfState, baseline: SelfState): number;
49
49
  /**
50
50
  * Compute emotional valence from chemistry.
51
51
  * Returns -1 (negative) to 1 (positive).
52
52
  */
53
- export declare function computeSnapshotValence(chemistry: ChemicalState): number;
53
+ export declare function computeSnapshotValence(state: SelfState): number;
54
54
  /**
55
55
  * Consolidate emotional history: mark core memories, fade weak ones.
56
56
  * Called at session end or when history overflows.
57
57
  */
58
- export declare function consolidateHistory(snapshots: ChemicalSnapshot[], maxEntries?: number): ChemicalSnapshot[];
58
+ export declare function consolidateHistory(snapshots: StateSnapshot[], maxEntries?: number): StateSnapshot[];
59
59
  /**
60
- * Retrieve memories related to current chemistry and stimulus.
61
- * Uses chemical similarity + stimulus matching + core memory bonus.
60
+ * Retrieve memories related to current self-state and stimulus.
61
+ * Uses state similarity + stimulus matching + core memory bonus.
62
62
  */
63
- export declare function retrieveRelatedMemories(history: ChemicalSnapshot[], currentChemistry: ChemicalState, stimulus: StimulusType | null, limit?: number): ChemicalSnapshot[];
63
+ export declare function retrieveRelatedMemories(history: StateSnapshot[], currentState: SelfState, stimulus: StimulusType | null, limit?: number): StateSnapshot[];
64
64
  /**
65
65
  * Load psyche state from workspace. Auto-initializes if missing.
66
66
  * Handles v1→v2 migration transparently.