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/README.md +67 -0
- package/dist/adapters/openclaw.js +7 -0
- package/dist/autonomic.d.ts +41 -0
- package/dist/autonomic.js +186 -0
- package/dist/circadian.d.ts +37 -0
- package/dist/circadian.js +97 -0
- package/dist/classify.d.ts +29 -2
- package/dist/classify.js +339 -53
- package/dist/cli.js +132 -13
- package/dist/core.d.ts +31 -2
- package/dist/core.js +246 -30
- package/dist/i18n.js +14 -0
- package/dist/index.d.ts +13 -5
- package/dist/index.js +11 -4
- package/dist/primary-systems.d.ts +55 -0
- package/dist/primary-systems.js +218 -0
- package/dist/profiles.d.ts +12 -1
- package/dist/profiles.js +42 -0
- package/dist/prompt.d.ts +26 -1
- package/dist/prompt.js +331 -33
- package/dist/psyche-file.d.ts +15 -1
- package/dist/psyche-file.js +147 -5
- package/dist/types.d.ts +16 -1
- package/dist/update.js +1 -1
- package/openclaw.plugin.json +35 -1
- package/package.json +4 -2
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 {
|
|
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.
|
|
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,
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
|
260
|
-
if (
|
|
261
|
-
state = mergeUpdates(state,
|
|
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
|
-
|
|
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:
|
|
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 {
|
|
35
|
-
export {
|
|
36
|
-
export {
|
|
37
|
-
export {
|
|
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;
|