psyche-ai 5.0.0 → 7.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/dist/core.js CHANGED
@@ -12,28 +12,39 @@
12
12
  // Orchestrates: chemistry, classify, prompt, profiles, guards, learning
13
13
  // ============================================================
14
14
  import { DEFAULT_RELATIONSHIP, DEFAULT_DRIVES, DEFAULT_LEARNING_STATE, DEFAULT_METACOGNITIVE_STATE, DEFAULT_PERSONHOOD_STATE } from "./types.js";
15
- import { applyDecay, applyStimulus, applyContagion, clamp } from "./chemistry.js";
15
+ import { MemoryStorageAdapter } from "./storage.js";
16
+ import { applyDecay, applyStimulus, applyContagion, clamp, describeEmotionalState } from "./chemistry.js";
16
17
  import { classifyStimulus } from "./classify.js";
17
18
  import { buildDynamicContext, buildProtocolContext, buildCompactContext } from "./prompt.js";
18
- import { getSensitivity, getBaseline, getDefaultSelfModel } from "./profiles.js";
19
+ import { getSensitivity, getBaseline, getDefaultSelfModel, traitsToBaseline } from "./profiles.js";
19
20
  import { isStimulusType } from "./guards.js";
20
- import { parsePsycheUpdate, mergeUpdates, updateAgreementStreak, pushSnapshot, } from "./psyche-file.js";
21
+ import { parsePsycheUpdate, mergeUpdates, updateAgreementStreak, pushSnapshot, compressSession, } from "./psyche-file.js";
21
22
  import { decayDrives, feedDrives, detectExistentialThreat, computeEffectiveBaseline, computeEffectiveSensitivity, } from "./drives.js";
22
23
  import { checkForUpdate } from "./update.js";
23
24
  import { evaluateOutcome, computeContextHash, updateLearnedVector, predictChemistry, recordPrediction, } from "./learning.js";
24
25
  import { assessMetacognition } from "./metacognition.js";
25
26
  import { buildDecisionContext } from "./decision-bias.js";
27
+ import { computeExperientialField } from "./experiential-field.js";
28
+ import { computeGenerativeSelf } from "./generative-self.js";
29
+ import { updateSharedIntentionality, buildSharedIntentionalityContext } from "./shared-intentionality.js";
30
+ import { assessEthics, buildEthicalContext } from "./ethics.js";
31
+ import { computeCircadianModulation, computeHomeostaticPressure } from "./circadian.js";
32
+ import { computeAutonomicResult } from "./autonomic.js";
33
+ import { computePrimarySystems, computeSystemInteractions, gatePrimarySystemsByAutonomic, describeBehavioralTendencies, } from "./primary-systems.js";
26
34
  const NOOP_LOGGER = { info: () => { }, warn: () => { }, debug: () => { } };
27
35
  // ── PsycheEngine ─────────────────────────────────────────────
28
36
  export class PsycheEngine {
29
37
  state = null;
30
38
  storage;
39
+ /** Whether the algorithm applied a stimulus in the last processInput call */
40
+ _lastAlgorithmApplied = false;
41
+ traits;
31
42
  cfg;
32
43
  protocolCache = new Map();
33
44
  /** Pending prediction from last processInput for auto-learning */
34
45
  pendingPrediction = null;
35
46
  constructor(config = {}, storage) {
36
- this.storage = storage;
47
+ this.traits = config.traits;
37
48
  this.cfg = {
38
49
  mbti: config.mbti ?? "INFJ",
39
50
  name: config.name ?? "agent",
@@ -42,7 +53,16 @@ export class PsycheEngine {
42
53
  emotionalContagionRate: config.emotionalContagionRate ?? 0.2,
43
54
  maxChemicalDelta: config.maxChemicalDelta ?? 25,
44
55
  compactMode: config.compactMode ?? true,
56
+ mode: config.mode ?? "natural",
57
+ personalityIntensity: config.personalityIntensity ?? 0.7,
45
58
  };
59
+ // If persist is false, use in-memory storage regardless of what was passed
60
+ if (config.persist === false) {
61
+ this.storage = new MemoryStorageAdapter();
62
+ }
63
+ else {
64
+ this.storage = storage;
65
+ }
46
66
  }
47
67
  /**
48
68
  * Load or create initial state. Must be called before processInput/processOutput.
@@ -65,6 +85,12 @@ export class PsycheEngine {
65
85
  loaded.personhood = { ...DEFAULT_PERSONHOOD_STATE };
66
86
  loaded.version = 6;
67
87
  }
88
+ // Migrate v6 → v7: add autonomic state and session tracking
89
+ if (loaded.version < 7) {
90
+ loaded.autonomicState = "ventral-vagal";
91
+ loaded.sessionStartedAt = new Date().toISOString();
92
+ loaded.version = 7;
93
+ }
68
94
  this.state = loaded;
69
95
  }
70
96
  else {
@@ -111,43 +137,56 @@ export class PsycheEngine {
111
137
  const decayedDrives = decayDrives(state.drives, minutesElapsed);
112
138
  // Compute effective baseline from drives (unsatisfied drives shift baseline)
113
139
  const effectiveBaseline = computeEffectiveBaseline(state.baseline, decayedDrives);
140
+ // P12: Apply circadian rhythm modulation to effective baseline
141
+ const circadianBaseline = computeCircadianModulation(now, effectiveBaseline);
114
142
  state = {
115
143
  ...state,
116
144
  drives: decayedDrives,
117
- current: applyDecay(state.current, effectiveBaseline, minutesElapsed),
145
+ current: applyDecay(state.current, circadianBaseline, minutesElapsed),
118
146
  updatedAt: now.toISOString(),
119
147
  };
120
148
  }
149
+ // P12: Track session start for homeostatic pressure
150
+ if (!state.sessionStartedAt) {
151
+ state = { ...state, sessionStartedAt: now.toISOString() };
152
+ }
153
+ // Apply homeostatic pressure (fatigue from extended sessions)
154
+ const sessionMinutes = (now.getTime() - new Date(state.sessionStartedAt).getTime()) / 60000;
155
+ const pressure = computeHomeostaticPressure(sessionMinutes);
156
+ if (pressure.cortAccumulation > 0 || pressure.daDepletion > 0 || pressure.neDepletion > 0) {
157
+ state = {
158
+ ...state,
159
+ current: {
160
+ ...state.current,
161
+ CORT: clamp(state.current.CORT + pressure.cortAccumulation * 0.1),
162
+ DA: clamp(state.current.DA - pressure.daDepletion * 0.1),
163
+ NE: clamp(state.current.NE - pressure.neDepletion * 0.1),
164
+ },
165
+ };
166
+ }
121
167
  // Classify user stimulus and apply chemistry
122
168
  let appliedStimulus = null;
123
169
  if (text.length > 0) {
124
170
  // Check for existential threats → direct survival drive hit
125
171
  const survivalHit = detectExistentialThreat(text);
172
+ let drives = state.drives;
126
173
  if (survivalHit < 0) {
127
- state = {
128
- ...state,
129
- drives: {
130
- ...state.drives,
131
- survival: Math.max(0, state.drives.survival + survivalHit),
132
- },
133
- };
174
+ drives = { ...drives, survival: Math.max(0, drives.survival + survivalHit) };
134
175
  }
135
- const classifications = classifyStimulus(text);
176
+ const recentStimuli = (state.emotionalHistory ?? []).slice(-3).map(s => s.stimulus);
177
+ const classifications = classifyStimulus(text, recentStimuli);
136
178
  const primary = classifications[0];
179
+ let current = state.current;
137
180
  if (primary && primary.confidence >= 0.5) {
138
181
  appliedStimulus = primary.type;
139
- // Feed drives from stimulus
140
- state = {
141
- ...state,
142
- drives: feedDrives(state.drives, primary.type),
143
- };
144
- // Apply stimulus with drive-modified sensitivity
145
- const effectiveSensitivity = computeEffectiveSensitivity(getSensitivity(state.mbti), state.drives, primary.type);
146
- state = {
147
- ...state,
148
- current: applyStimulus(state.current, primary.type, effectiveSensitivity, this.cfg.maxChemicalDelta, NOOP_LOGGER),
149
- };
182
+ // Feed drives from stimulus, then apply stimulus with drive-modified sensitivity
183
+ drives = feedDrives(drives, primary.type);
184
+ const effectiveSensitivity = computeEffectiveSensitivity(getSensitivity(state.mbti), drives, primary.type);
185
+ const modeMultiplier = this.cfg.mode === "work" ? 0.3 : this.cfg.mode === "companion" ? 1.5 : 1.0;
186
+ const effectiveMaxDelta = this.cfg.mode === "work" ? 5 : this.cfg.maxChemicalDelta;
187
+ current = applyStimulus(current, primary.type, effectiveSensitivity * this.cfg.personalityIntensity * modeMultiplier, effectiveMaxDelta, NOOP_LOGGER);
150
188
  }
189
+ state = { ...state, drives, current };
151
190
  }
152
191
  // Conversation warmth: sustained interaction → gentle DA/OT rise, CORT drop
153
192
  // Simulates the natural "warm glow" of being in continuous conversation
@@ -164,6 +203,19 @@ export class PsycheEngine {
164
203
  },
165
204
  };
166
205
  }
206
+ // ── Locale (used by multiple subsystems below) ──────────
207
+ const locale = state.meta.locale ?? this.cfg.locale;
208
+ // ── P7: Autonomic nervous system — Polyvagal state ────────
209
+ const autonomicResult = computeAutonomicResult(state.current, state.drives, state.autonomicState ?? null, minutesElapsed, locale);
210
+ state = {
211
+ ...state,
212
+ autonomicState: autonomicResult.state,
213
+ };
214
+ // ── P9: Primary emotional systems (Panksepp) ──────────────
215
+ const rawSystems = computePrimarySystems(state.current, state.drives, appliedStimulus);
216
+ const interactedSystems = computeSystemInteractions(rawSystems);
217
+ const gatedSystems = gatePrimarySystemsByAutonomic(interactedSystems, autonomicResult.state);
218
+ const primarySystemsDescription = describeBehavioralTendencies(gatedSystems, locale);
167
219
  // ── Metacognition: assess emotional state before acting ────
168
220
  const metacognitiveAssessment = assessMetacognition(state, appliedStimulus ?? "casual", state.learning.outcomeHistory);
169
221
  // Apply self-soothing regulation if suggested with high confidence
@@ -191,6 +243,8 @@ export class PsycheEngine {
191
243
  ...state,
192
244
  meta: { ...state.meta, totalInteractions: state.meta.totalInteractions + 1 },
193
245
  };
246
+ // Track whether algorithm applied a stimulus (for LLM-assisted fallback in processOutput)
247
+ this._lastAlgorithmApplied = appliedStimulus !== null;
194
248
  // ── Generate prediction for next turn's auto-learning ────
195
249
  if (appliedStimulus) {
196
250
  const ctxHash = computeContextHash(state, opts?.userId);
@@ -206,21 +260,93 @@ export class PsycheEngine {
206
260
  else {
207
261
  this.pendingPrediction = null;
208
262
  }
263
+ // ── P6: Digital Personhood computations ────────────────────
264
+ // Experiential field — unified inner experience
265
+ const experientialField = computeExperientialField(state, metacognitiveAssessment);
266
+ // Shared intentionality — theory of mind + joint attention
267
+ const sharedState = updateSharedIntentionality(state, appliedStimulus, opts?.userId);
268
+ // Ethics — emotional self-care check
269
+ const ethicalAssessment = assessEthics(state);
270
+ // Generative self — update identity narrative periodically (every 10 turns)
271
+ if (state.meta.totalInteractions % 10 === 0 && state.meta.totalInteractions > 0) {
272
+ const selfModel = computeGenerativeSelf(state);
273
+ state = {
274
+ ...state,
275
+ personhood: {
276
+ ...state.personhood,
277
+ identityNarrative: selfModel.identityNarrative,
278
+ growthDirection: selfModel.growthArc.direction,
279
+ causalInsights: selfModel.causalInsights.slice(0, 20).map((ci) => ({
280
+ trait: ci.trait,
281
+ because: ci.because,
282
+ confidence: ci.confidence,
283
+ discoveredAt: new Date().toISOString(),
284
+ })),
285
+ },
286
+ };
287
+ }
288
+ // Persist ethical concerns if significant
289
+ if (ethicalAssessment.ethicalHealth < 0.7) {
290
+ const newConcerns = ethicalAssessment.concerns
291
+ .filter((c) => c.severity > 0.4)
292
+ .map((c) => ({ type: c.type, severity: c.severity, timestamp: new Date().toISOString() }));
293
+ if (newConcerns.length > 0) {
294
+ state = {
295
+ ...state,
296
+ personhood: {
297
+ ...state.personhood,
298
+ ethicalConcernHistory: [
299
+ ...state.personhood.ethicalConcernHistory.slice(-14),
300
+ ...newConcerns,
301
+ ],
302
+ },
303
+ };
304
+ }
305
+ }
306
+ // Persist theory of mind
307
+ if (sharedState.theoryOfMind.confidence > 0.3) {
308
+ const userId = opts?.userId ?? "_default";
309
+ state = {
310
+ ...state,
311
+ personhood: {
312
+ ...state.personhood,
313
+ theoryOfMind: {
314
+ ...state.personhood.theoryOfMind,
315
+ [userId]: {
316
+ estimatedMood: sharedState.theoryOfMind.estimatedMood,
317
+ estimatedIntent: sharedState.theoryOfMind.estimatedIntent,
318
+ confidence: sharedState.theoryOfMind.confidence,
319
+ lastUpdated: sharedState.theoryOfMind.lastUpdated,
320
+ },
321
+ },
322
+ },
323
+ };
324
+ }
209
325
  // Persist
210
326
  this.state = state;
211
327
  await this.storage.save(state);
212
- const locale = state.meta.locale ?? this.cfg.locale;
213
328
  // Build metacognitive and decision context strings
214
329
  const metacogNote = metacognitiveAssessment.metacognitiveNote;
215
330
  const decisionCtx = buildDecisionContext(state);
331
+ const ethicsCtx = buildEthicalContext(ethicalAssessment, locale);
332
+ const sharedCtx = buildSharedIntentionalityContext(sharedState, locale);
333
+ const experientialNarrative = experientialField.narrative || undefined;
216
334
  if (this.cfg.compactMode) {
217
335
  return {
218
336
  systemContext: "",
219
337
  dynamicContext: buildCompactContext(state, opts?.userId, {
220
338
  userText: text || undefined,
221
339
  algorithmStimulus: appliedStimulus,
340
+ personalityIntensity: this.cfg.personalityIntensity,
222
341
  metacognitiveNote: metacogNote || undefined,
223
342
  decisionContext: decisionCtx || undefined,
343
+ ethicsContext: ethicsCtx || undefined,
344
+ sharedIntentionalityContext: sharedCtx || undefined,
345
+ experientialNarrative: experientialNarrative,
346
+ // Only inject autonomic description when NOT in default calm state (saves ~25 tokens)
347
+ autonomicDescription: autonomicResult.state !== "ventral-vagal"
348
+ ? autonomicResult.description : undefined,
349
+ primarySystemsDescription: primarySystemsDescription || undefined,
224
350
  }),
225
351
  stimulus: appliedStimulus,
226
352
  };
@@ -230,6 +356,12 @@ export class PsycheEngine {
230
356
  dynamicContext: buildDynamicContext(state, opts?.userId, {
231
357
  metacognitiveNote: metacogNote || undefined,
232
358
  decisionContext: decisionCtx || undefined,
359
+ ethicsContext: ethicsCtx || undefined,
360
+ sharedIntentionalityContext: sharedCtx || undefined,
361
+ experientialNarrative: experientialNarrative,
362
+ autonomicDescription: autonomicResult.state !== "ventral-vagal"
363
+ ? autonomicResult.description : undefined,
364
+ primarySystemsDescription: primarySystemsDescription || undefined,
233
365
  }),
234
366
  stimulus: appliedStimulus,
235
367
  };
@@ -256,10 +388,23 @@ export class PsycheEngine {
256
388
  state = updateAgreementStreak(state, text);
257
389
  // Parse and merge <psyche_update> from LLM output
258
390
  if (text.includes("<psyche_update>")) {
259
- const updates = parsePsycheUpdate(text, NOOP_LOGGER);
260
- if (updates) {
261
- state = mergeUpdates(state, updates, this.cfg.maxChemicalDelta, opts?.userId);
391
+ const parseResult = parsePsycheUpdate(text, NOOP_LOGGER);
392
+ if (parseResult) {
393
+ state = mergeUpdates(state, parseResult.state, this.cfg.maxChemicalDelta, opts?.userId);
262
394
  stateChanged = true;
395
+ // LLM-assisted classification: if algorithm didn't apply a stimulus
396
+ // but LLM classified one, retroactively apply chemistry + drives
397
+ if (parseResult.llmStimulus && !this._lastAlgorithmApplied) {
398
+ state = {
399
+ ...state,
400
+ drives: feedDrives(state.drives, parseResult.llmStimulus),
401
+ };
402
+ const effectiveSensitivity = computeEffectiveSensitivity(getSensitivity(state.mbti), state.drives, parseResult.llmStimulus);
403
+ state = {
404
+ ...state,
405
+ current: applyStimulus(state.current, parseResult.llmStimulus, effectiveSensitivity, this.cfg.maxChemicalDelta, NOOP_LOGGER),
406
+ };
407
+ }
263
408
  }
264
409
  }
265
410
  // Persist
@@ -328,6 +473,21 @@ export class PsycheEngine {
328
473
  }
329
474
  return cached;
330
475
  }
476
+ /**
477
+ * End the current session: compress emotionalHistory into a rich summary
478
+ * stored in relationship.memory[], then clear the history.
479
+ * No-op if history has fewer than 2 entries.
480
+ */
481
+ async endSession(opts) {
482
+ let state = this.ensureInitialized();
483
+ if ((state.emotionalHistory ?? []).length < 2)
484
+ return;
485
+ state = compressSession(state, opts?.userId);
486
+ // Reset session tracking for homeostatic pressure
487
+ state = { ...state, sessionStartedAt: undefined };
488
+ this.state = state;
489
+ await this.storage.save(state);
490
+ }
331
491
  // ── Private ──────────────────────────────────────────────
332
492
  ensureInitialized() {
333
493
  if (!this.state) {
@@ -337,11 +497,12 @@ export class PsycheEngine {
337
497
  }
338
498
  createDefaultState() {
339
499
  const { mbti, name, locale } = this.cfg;
340
- const baseline = getBaseline(mbti);
500
+ // Use Big Five traits if provided, otherwise use MBTI baseline
501
+ const baseline = this.traits ? traitsToBaseline(this.traits).baseline : getBaseline(mbti);
341
502
  const selfModel = getDefaultSelfModel(mbti);
342
503
  const now = new Date().toISOString();
343
504
  return {
344
- version: 6,
505
+ version: 7,
345
506
  mbti,
346
507
  baseline,
347
508
  current: { ...baseline },
@@ -356,12 +517,67 @@ export class PsycheEngine {
356
517
  learning: { ...DEFAULT_LEARNING_STATE },
357
518
  metacognition: { ...DEFAULT_METACOGNITIVE_STATE },
358
519
  personhood: { ...DEFAULT_PERSONHOOD_STATE },
520
+ autonomicState: "ventral-vagal",
521
+ sessionStartedAt: now,
359
522
  meta: {
360
523
  agentName: name,
361
524
  createdAt: now,
362
525
  totalInteractions: 0,
363
526
  locale,
527
+ mode: this.cfg.mode,
364
528
  },
365
529
  };
366
530
  }
531
+ /**
532
+ * Reset state to baseline. Optionally preserves relationships.
533
+ */
534
+ async resetState(opts) {
535
+ let state = this.ensureInitialized();
536
+ const baseline = this.traits ? traitsToBaseline(this.traits).baseline : getBaseline(state.mbti);
537
+ state = {
538
+ ...state,
539
+ current: { ...baseline },
540
+ baseline,
541
+ drives: { ...DEFAULT_DRIVES },
542
+ emotionalHistory: [],
543
+ agreementStreak: 0,
544
+ lastDisagreement: null,
545
+ empathyLog: null,
546
+ autonomicState: "ventral-vagal",
547
+ sessionStartedAt: undefined,
548
+ updatedAt: new Date().toISOString(),
549
+ relationships: opts?.preserveRelationships !== false
550
+ ? state.relationships
551
+ : { _default: { ...DEFAULT_RELATIONSHIP } },
552
+ };
553
+ this.state = state;
554
+ await this.storage.save(state);
555
+ }
556
+ /**
557
+ * Get a single-line status summary with emoji.
558
+ */
559
+ getStatusSummary() {
560
+ const state = this.ensureInitialized();
561
+ const locale = state.meta.locale ?? "zh";
562
+ const emotion = describeEmotionalState(state.current, locale);
563
+ const { DA, CORT } = state.current;
564
+ // Emoji based on dominant state
565
+ let emoji = "\u{1F610}";
566
+ if (DA > 70 && CORT < 40)
567
+ emoji = "\u{1F60A}";
568
+ else if (DA > 60)
569
+ emoji = "\u{1F642}";
570
+ else if (CORT > 60)
571
+ emoji = "\u{1F630}";
572
+ else if (DA < 35)
573
+ emoji = "\u{1F614}";
574
+ // Check for hungry drives
575
+ const hungryDrives = Object.entries(state.drives)
576
+ .filter(([, v]) => v < 40)
577
+ .map(([k]) => k);
578
+ const driveWarning = hungryDrives.length > 0
579
+ ? ` | \u26A0\uFE0F${hungryDrives.join(",")}`
580
+ : "";
581
+ return `${emoji} ${emotion} | DA:${Math.round(DA)} CORT:${Math.round(CORT)}${driveWarning}`;
582
+ }
367
583
  }
package/dist/i18n.js CHANGED
@@ -82,6 +82,13 @@ const STRINGS = {
82
82
  "log.default_mbti": "未检测到MBTI类型,使用默认值: {type}",
83
83
  "log.permission_error": "无权限访问: {path}",
84
84
  "log.parse_debug": "parsePsycheUpdate 未匹配,原始文本片段: {snippet}",
85
+ // Mode descriptions
86
+ "mode.natural": "自然模式——完整情绪体验",
87
+ "mode.work": "工作模式——最小情绪,专注任务",
88
+ "mode.companion": "伴侣模式——强化情绪表达",
89
+ // First meeting
90
+ "firstMeet.inner": "这是你第一次遇见对方。你感到好奇和一点紧张。你想了解他们,但不想表现得太急切。",
91
+ "firstMeet.behavior": "保持自然,微微好奇。不要过度热情,也不要太冷淡。",
85
92
  },
86
93
  en: {
87
94
  "protocol.title": "Psyche Protocol",
@@ -156,6 +163,13 @@ const STRINGS = {
156
163
  "log.default_mbti": "MBTI type not detected, using default: {type}",
157
164
  "log.permission_error": "Permission denied: {path}",
158
165
  "log.parse_debug": "parsePsycheUpdate no match, raw snippet: {snippet}",
166
+ // Mode descriptions
167
+ "mode.natural": "Natural mode — full emotional experience",
168
+ "mode.work": "Work mode — minimal emotions, task-focused",
169
+ "mode.companion": "Companion mode — enhanced emotional expression",
170
+ // First meeting
171
+ "firstMeet.inner": "This is your first time meeting them. You feel curious and a little nervous. You want to know them, but don't want to seem too eager.",
172
+ "firstMeet.behavior": "Be natural, slightly curious. Don't be overly warm, and don't be too cold.",
159
173
  },
160
174
  };
161
175
  /**
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export { PsycheEngine } from "./core.js";
2
2
  export type { PsycheEngineConfig, ProcessInputResult, ProcessOutputResult, ProcessOutcomeResult } from "./core.js";
3
3
  export { FileStorageAdapter, MemoryStorageAdapter } from "./storage.js";
4
4
  export type { StorageAdapter } from "./storage.js";
5
- export type { PsycheState, MBTIType, Locale, StimulusType, ChemicalState, ChemicalSnapshot, SelfModel, RelationshipState, EmpathyEntry, EmotionPattern, DriveType, InnateDrives, LearningState, LearnedVectorAdjustment, PredictionRecord, OutcomeScore, OutcomeSignals, AttachmentStyle, AttachmentData, MetacognitiveState, RegulationRecord, DefensePatternRecord, RegulationStrategyType, DefenseMechanismType, PersonhoodState, PersistedCausalInsight, GrowthDirection, } from "./types.js";
5
+ export type { PsycheState, MBTIType, Locale, StimulusType, ChemicalState, ChemicalSnapshot, SelfModel, RelationshipState, EmpathyEntry, EmotionPattern, DriveType, InnateDrives, LearningState, LearnedVectorAdjustment, PredictionRecord, OutcomeScore, OutcomeSignals, AttachmentStyle, AttachmentData, MetacognitiveState, RegulationRecord, DefensePatternRecord, RegulationStrategyType, DefenseMechanismType, PersonhoodState, PersistedCausalInsight, GrowthDirection, PersonalityTraits, PsycheMode, } from "./types.js";
6
6
  export { CHEMICAL_KEYS, CHEMICAL_NAMES, CHEMICAL_NAMES_ZH, DEFAULT_RELATIONSHIP, DEFAULT_DRIVES, DEFAULT_LEARNING_STATE, DEFAULT_METACOGNITIVE_STATE, DEFAULT_PERSONHOOD_STATE, DEFAULT_ATTACHMENT, DRIVE_KEYS, DRIVE_NAMES_ZH, } from "./types.js";
7
7
  export { computeSelfReflection, computeEmotionalTendency, buildSelfReflectionContext } from "./self-recognition.js";
8
8
  export type { SelfReflection } from "./self-recognition.js";
@@ -31,7 +31,15 @@ export { updateSharedIntentionality, estimateOtherMood, buildSharedIntentionalit
31
31
  export type { SharedIntentionalityState, TheoryOfMindModel, JointAttentionTopic, GoalAlignment } from "./shared-intentionality.js";
32
32
  export { assessEthics, detectIntermittentReinforcement, detectDependencyRisk, buildEthicalContext, } from "./ethics.js";
33
33
  export type { EthicalAssessment, EthicalConcern, SelfProtectionAction } from "./ethics.js";
34
- export { classifyStimulus, getPrimaryStimulus } from "./classify.js";
35
- export { buildProtocolContext, buildDynamicContext, buildCompactContext, isNearBaseline } from "./prompt.js";
36
- export { describeEmotionalState, getExpressionHint, getBehaviorGuide } from "./chemistry.js";
37
- export { getBaseline, getTemperament, getSensitivity, getDefaultSelfModel } from "./profiles.js";
34
+ export { computeAutonomicResult, computeAutonomicState, gateEmotions, getTransitionTime, describeAutonomicState } from "./autonomic.js";
35
+ export type { AutonomicState, AutonomicResult, AutonomicTransition } from "./autonomic.js";
36
+ export { computeCircadianModulation, computeHomeostaticPressure, getCircadianPhase } from "./circadian.js";
37
+ export type { CircadianPhase } from "./circadian.js";
38
+ export { computePrimarySystems, computeSystemInteractions, gatePrimarySystemsByAutonomic, getDominantSystems, describeBehavioralTendencies, PRIMARY_SYSTEM_NAMES, } from "./primary-systems.js";
39
+ export type { PrimarySystemName, PrimarySystemLevels, BehavioralTendency, DominantSystem, } from "./primary-systems.js";
40
+ export { classifyStimulus, getPrimaryStimulus, scoreSentiment, scoreEmoji } from "./classify.js";
41
+ export { buildProtocolContext, buildDynamicContext, buildCompactContext, isNearBaseline, getNearBaselineThreshold } from "./prompt.js";
42
+ export { describeEmotionalState, getExpressionHint, getBehaviorGuide, detectEmotions } from "./chemistry.js";
43
+ export { getBaseline, getTemperament, getSensitivity, getDefaultSelfModel, traitsToBaseline, mbtiToTraits } from "./profiles.js";
44
+ export { migrateToLatest, compressSession, parsePsycheUpdate } from "./psyche-file.js";
45
+ export type { PsycheUpdateResult } from "./psyche-file.js";
package/dist/index.js CHANGED
@@ -41,8 +41,15 @@ export { computeGenerativeSelf, predictSelfReaction, detectInternalConflicts, bu
41
41
  export { updateSharedIntentionality, estimateOtherMood, buildSharedIntentionalityContext } from "./shared-intentionality.js";
42
42
  // Emotional ethics (P6)
43
43
  export { assessEthics, detectIntermittentReinforcement, detectDependencyRisk, buildEthicalContext, } from "./ethics.js";
44
+ // Autonomic nervous system (P7)
45
+ export { computeAutonomicResult, computeAutonomicState, gateEmotions, getTransitionTime, describeAutonomicState } from "./autonomic.js";
46
+ // Circadian rhythms (P12)
47
+ export { computeCircadianModulation, computeHomeostaticPressure, getCircadianPhase } from "./circadian.js";
48
+ // Primary emotional systems — Panksepp (P9)
49
+ export { computePrimarySystems, computeSystemInteractions, gatePrimarySystemsByAutonomic, getDominantSystems, describeBehavioralTendencies, PRIMARY_SYSTEM_NAMES, } from "./primary-systems.js";
44
50
  // Utilities — for custom adapter / advanced use
45
- export { classifyStimulus, getPrimaryStimulus } from "./classify.js";
46
- export { buildProtocolContext, buildDynamicContext, buildCompactContext, isNearBaseline } from "./prompt.js";
47
- export { describeEmotionalState, getExpressionHint, getBehaviorGuide } from "./chemistry.js";
48
- export { getBaseline, getTemperament, getSensitivity, getDefaultSelfModel } from "./profiles.js";
51
+ export { classifyStimulus, getPrimaryStimulus, scoreSentiment, scoreEmoji } from "./classify.js";
52
+ export { buildProtocolContext, buildDynamicContext, buildCompactContext, isNearBaseline, getNearBaselineThreshold } from "./prompt.js";
53
+ export { describeEmotionalState, getExpressionHint, getBehaviorGuide, detectEmotions } from "./chemistry.js";
54
+ export { getBaseline, getTemperament, getSensitivity, getDefaultSelfModel, traitsToBaseline, mbtiToTraits } from "./profiles.js";
55
+ export { migrateToLatest, compressSession, parsePsycheUpdate } from "./psyche-file.js";
@@ -0,0 +1,55 @@
1
+ import type { ChemicalState, InnateDrives, StimulusType, Locale } from "./types.js";
2
+ import type { AutonomicState } from "./autonomic.js";
3
+ export type PrimarySystemName = "SEEKING" | "RAGE" | "FEAR" | "LUST" | "CARE" | "PANIC_GRIEF" | "PLAY";
4
+ export declare const PRIMARY_SYSTEM_NAMES: PrimarySystemName[];
5
+ /** Activation levels for all 7 systems (0-100 each) */
6
+ export type PrimarySystemLevels = Record<PrimarySystemName, number>;
7
+ /** Behavioral tendency produced by a dominant system */
8
+ export interface BehavioralTendency {
9
+ description: string;
10
+ descriptionZh: string;
11
+ }
12
+ /** A dominant system with its level and tendency */
13
+ export interface DominantSystem {
14
+ system: PrimarySystemName;
15
+ level: number;
16
+ tendency: BehavioralTendency;
17
+ }
18
+ /**
19
+ * Compute raw activation levels for all 7 primary systems
20
+ * from chemistry, drives, and optional recent stimulus.
21
+ *
22
+ * Each system is a weighted combination of chemical values and drive states.
23
+ * recentStimulus provides a small contextual boost.
24
+ */
25
+ export declare function computePrimarySystems(chemistry: ChemicalState, drives: InnateDrives, recentStimulus: StimulusType | null): PrimarySystemLevels;
26
+ /**
27
+ * Apply inter-system interactions:
28
+ * - FEAR suppresses PLAY and SEEKING
29
+ * - SEEKING suppresses PANIC_GRIEF
30
+ * - RAGE suppresses CARE
31
+ * - CARE and PLAY can co-activate (no suppression)
32
+ * - PANIC_GRIEF and RAGE can co-activate (grief-rage)
33
+ *
34
+ * Suppression is proportional: high suppressor → strong suppression.
35
+ * Below threshold (~40), suppression is negligible.
36
+ */
37
+ export declare function computeSystemInteractions(levels: PrimarySystemLevels): PrimarySystemLevels;
38
+ /**
39
+ * Gate primary systems by autonomic state.
40
+ * - ventral-vagal: all systems pass through
41
+ * - sympathetic: amplify FEAR/RAGE, suppress PLAY/CARE/SEEKING
42
+ * - dorsal-vagal: suppress almost everything, allow PANIC_GRIEF and FEAR
43
+ */
44
+ export declare function gatePrimarySystemsByAutonomic(levels: PrimarySystemLevels, autonomicState: AutonomicState): PrimarySystemLevels;
45
+ /**
46
+ * Get dominant systems (above threshold), sorted by activation descending.
47
+ * Each includes its behavioral tendency description.
48
+ */
49
+ export declare function getDominantSystems(levels: PrimarySystemLevels, threshold?: number): DominantSystem[];
50
+ /**
51
+ * Generate a concise behavioral tendency description from system levels.
52
+ * Returns empty string when no system is dominant (token-efficient).
53
+ * Max 2 tendencies to keep under ~100 chars.
54
+ */
55
+ export declare function describeBehavioralTendencies(levels: PrimarySystemLevels, locale: Locale): string;