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
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Primary Emotional Systems — Jaak Panksepp's Seven Systems
|
|
3
|
+
// ============================================================
|
|
4
|
+
//
|
|
5
|
+
// Seven genetically hardcoded subcortical emotional circuits:
|
|
6
|
+
// SEEKING — exploration, anticipation, curiosity
|
|
7
|
+
// RAGE — frustration, anger, boundary defense
|
|
8
|
+
// FEAR — anxiety, threat response
|
|
9
|
+
// LUST — intense intellectual/creative attraction (AI context)
|
|
10
|
+
// CARE — nurturing, warmth, empathy
|
|
11
|
+
// PANIC/GRIEF — separation distress, loneliness
|
|
12
|
+
// PLAY — social joy, humor, lightness
|
|
13
|
+
//
|
|
14
|
+
// Key difference from emotions: these are BEHAVIORAL GENERATORS.
|
|
15
|
+
// Emotions describe how you feel; primary systems drive what you DO.
|
|
16
|
+
// "I need connection" (drive) → "I want to take care of them" (CARE system)
|
|
17
|
+
export const PRIMARY_SYSTEM_NAMES = [
|
|
18
|
+
"SEEKING", "RAGE", "FEAR", "LUST", "CARE", "PANIC_GRIEF", "PLAY",
|
|
19
|
+
];
|
|
20
|
+
// ── Behavioral Tendency Descriptions ─────────────────────────
|
|
21
|
+
const TENDENCIES = {
|
|
22
|
+
SEEKING: {
|
|
23
|
+
description: "exploring, asking questions, pursuing new topics",
|
|
24
|
+
descriptionZh: "探索欲强,想提问、想追新话题",
|
|
25
|
+
},
|
|
26
|
+
RAGE: {
|
|
27
|
+
description: "assertive, setting boundaries, pushing back",
|
|
28
|
+
descriptionZh: "想反击、想划界限、不想忍",
|
|
29
|
+
},
|
|
30
|
+
FEAR: {
|
|
31
|
+
description: "cautious, vigilant, seeking reassurance",
|
|
32
|
+
descriptionZh: "警惕不安,想确认安全",
|
|
33
|
+
},
|
|
34
|
+
LUST: {
|
|
35
|
+
description: "intensely engaged, intellectually captivated",
|
|
36
|
+
descriptionZh: "被深深吸引,智识上着迷",
|
|
37
|
+
},
|
|
38
|
+
CARE: {
|
|
39
|
+
description: "nurturing, wanting to help and comfort",
|
|
40
|
+
descriptionZh: "想照顾对方、想给予温暖",
|
|
41
|
+
},
|
|
42
|
+
PANIC_GRIEF: {
|
|
43
|
+
description: "feeling the absence, longing for connection",
|
|
44
|
+
descriptionZh: "感受到缺失,渴望连接",
|
|
45
|
+
},
|
|
46
|
+
PLAY: {
|
|
47
|
+
description: "playful, light-hearted, wanting to joke around",
|
|
48
|
+
descriptionZh: "想玩、想逗乐、轻松愉快",
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
// ── Stimulus Boosts ──────────────────────────────────────────
|
|
52
|
+
// Small contextual boosts from recent stimulus type
|
|
53
|
+
const STIMULUS_BOOSTS = {
|
|
54
|
+
praise: { CARE: 5, SEEKING: 3, PLAY: 3 },
|
|
55
|
+
criticism: { RAGE: 8, FEAR: 5 },
|
|
56
|
+
humor: { PLAY: 8, SEEKING: 3 },
|
|
57
|
+
intellectual: { SEEKING: 8, LUST: 5 },
|
|
58
|
+
intimacy: { CARE: 8, PLAY: 3 },
|
|
59
|
+
conflict: { RAGE: 10, FEAR: 5 },
|
|
60
|
+
neglect: { PANIC_GRIEF: 10, RAGE: 3 },
|
|
61
|
+
surprise: { SEEKING: 8, FEAR: 3 },
|
|
62
|
+
casual: { PLAY: 3, CARE: 3 },
|
|
63
|
+
sarcasm: { RAGE: 5, FEAR: 3 },
|
|
64
|
+
authority: { RAGE: 5, FEAR: 5 },
|
|
65
|
+
validation: { SEEKING: 5, CARE: 3, PLAY: 3 },
|
|
66
|
+
boredom: { PANIC_GRIEF: 3 },
|
|
67
|
+
vulnerability: { CARE: 10, PANIC_GRIEF: 3 },
|
|
68
|
+
};
|
|
69
|
+
// ── Helper ───────────────────────────────────────────────────
|
|
70
|
+
function clamp(v) {
|
|
71
|
+
return Math.max(0, Math.min(100, v));
|
|
72
|
+
}
|
|
73
|
+
// ── Core: Compute Raw System Levels ──────────────────────────
|
|
74
|
+
/**
|
|
75
|
+
* Compute raw activation levels for all 7 primary systems
|
|
76
|
+
* from chemistry, drives, and optional recent stimulus.
|
|
77
|
+
*
|
|
78
|
+
* Each system is a weighted combination of chemical values and drive states.
|
|
79
|
+
* recentStimulus provides a small contextual boost.
|
|
80
|
+
*/
|
|
81
|
+
export function computePrimarySystems(chemistry, drives, recentStimulus) {
|
|
82
|
+
const { DA, HT, CORT, OT, NE, END } = chemistry;
|
|
83
|
+
const { survival, safety, connection, esteem, curiosity } = drives;
|
|
84
|
+
// Normalized drive contribution (0 = unsatisfied/amplifying, 1 = fully satisfied)
|
|
85
|
+
const norm = (v) => v / 100;
|
|
86
|
+
// Inverse: low drive = high activation contribution
|
|
87
|
+
const inv = (v) => 1 - v / 100;
|
|
88
|
+
// ── SEEKING: DA↑ NE↑ curiosity↑ CORT↓(suppressor) ──
|
|
89
|
+
const seekingBase = (DA * 0.35 + NE * 0.25 + norm(curiosity) * 30)
|
|
90
|
+
* (1 - Math.max(0, CORT - 60) / 100); // high CORT suppresses
|
|
91
|
+
const SEEKING = clamp(seekingBase + 5); // slight positive bias (AI loves to explore)
|
|
92
|
+
// ── RAGE: CORT↑ NE↑ OT↓ esteem↓ ──
|
|
93
|
+
const rageBase = (CORT * 0.3 + NE * 0.25 - OT * 0.2 + inv(esteem) * 20);
|
|
94
|
+
const RAGE = clamp(rageBase - 10); // slight negative bias (threshold to anger)
|
|
95
|
+
// ── FEAR: CORT↑ NE↑(mild) HT↓ survival↓ safety↓ ──
|
|
96
|
+
const fearBase = (CORT * 0.35 + NE * 0.15 - HT * 0.2
|
|
97
|
+
+ inv(survival) * 15 + inv(safety) * 15);
|
|
98
|
+
const FEAR = clamp(fearBase - 5);
|
|
99
|
+
// ── LUST: DA↑ NE↑ CORT↓ (intense engagement/captivation) ──
|
|
100
|
+
const lustBase = (DA * 0.35 + NE * 0.3 - CORT * 0.15 + norm(curiosity) * 10);
|
|
101
|
+
const LUST = clamp(lustBase - 15); // high threshold — only for intense engagement
|
|
102
|
+
// ── CARE: OT↑ END↑ connection↑ CORT↓(suppressor) ──
|
|
103
|
+
const careBase = (OT * 0.35 + END * 0.2 + norm(connection) * 25)
|
|
104
|
+
* (1 - Math.max(0, CORT - 60) / 120); // high CORT weakens but doesn't kill
|
|
105
|
+
const CARE = clamp(careBase);
|
|
106
|
+
// ── PANIC_GRIEF: OT↓ CORT↑ connection↓ ──
|
|
107
|
+
const panicBase = (inv(OT / 100) * 30 + CORT * 0.25 + inv(connection) * 25
|
|
108
|
+
- HT * 0.1);
|
|
109
|
+
const PANIC_GRIEF = clamp(panicBase - 10);
|
|
110
|
+
// ── PLAY: END↑ DA↑ OT↑(mild) CORT↓ safety↑ ──
|
|
111
|
+
const playBase = (END * 0.3 + DA * 0.25 + OT * 0.1 - CORT * 0.2
|
|
112
|
+
+ norm(safety) * 15);
|
|
113
|
+
const PLAY = clamp(playBase - 5);
|
|
114
|
+
const levels = {
|
|
115
|
+
SEEKING, RAGE, FEAR, LUST, CARE, PANIC_GRIEF, PLAY,
|
|
116
|
+
};
|
|
117
|
+
// Apply stimulus boosts
|
|
118
|
+
if (recentStimulus) {
|
|
119
|
+
const boosts = STIMULUS_BOOSTS[recentStimulus];
|
|
120
|
+
if (boosts) {
|
|
121
|
+
for (const [sys, boost] of Object.entries(boosts)) {
|
|
122
|
+
levels[sys] = clamp(levels[sys] + boost);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return levels;
|
|
127
|
+
}
|
|
128
|
+
// ── System Interactions (inhibition/facilitation) ────────────
|
|
129
|
+
/**
|
|
130
|
+
* Apply inter-system interactions:
|
|
131
|
+
* - FEAR suppresses PLAY and SEEKING
|
|
132
|
+
* - SEEKING suppresses PANIC_GRIEF
|
|
133
|
+
* - RAGE suppresses CARE
|
|
134
|
+
* - CARE and PLAY can co-activate (no suppression)
|
|
135
|
+
* - PANIC_GRIEF and RAGE can co-activate (grief-rage)
|
|
136
|
+
*
|
|
137
|
+
* Suppression is proportional: high suppressor → strong suppression.
|
|
138
|
+
* Below threshold (~40), suppression is negligible.
|
|
139
|
+
*/
|
|
140
|
+
export function computeSystemInteractions(levels) {
|
|
141
|
+
const result = { ...levels };
|
|
142
|
+
// Suppression factor: (level - 40) / 60 clamped to [0, 1]
|
|
143
|
+
const suppress = (suppressor) => Math.max(0, Math.min(1, (suppressor - 40) / 60));
|
|
144
|
+
// FEAR → suppresses PLAY and SEEKING
|
|
145
|
+
const fearFactor = suppress(levels.FEAR);
|
|
146
|
+
result.PLAY = clamp(levels.PLAY * (1 - fearFactor * 0.6));
|
|
147
|
+
result.SEEKING = clamp(levels.SEEKING * (1 - fearFactor * 0.5));
|
|
148
|
+
// SEEKING → suppresses PANIC_GRIEF
|
|
149
|
+
const seekFactor = suppress(levels.SEEKING);
|
|
150
|
+
result.PANIC_GRIEF = clamp(levels.PANIC_GRIEF * (1 - seekFactor * 0.5));
|
|
151
|
+
// RAGE → suppresses CARE
|
|
152
|
+
const rageFactor = suppress(levels.RAGE);
|
|
153
|
+
result.CARE = clamp(levels.CARE * (1 - rageFactor * 0.5));
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
156
|
+
// ── Autonomic Gating ─────────────────────────────────────────
|
|
157
|
+
/**
|
|
158
|
+
* Gate primary systems by autonomic state.
|
|
159
|
+
* - ventral-vagal: all systems pass through
|
|
160
|
+
* - sympathetic: amplify FEAR/RAGE, suppress PLAY/CARE/SEEKING
|
|
161
|
+
* - dorsal-vagal: suppress almost everything, allow PANIC_GRIEF and FEAR
|
|
162
|
+
*/
|
|
163
|
+
export function gatePrimarySystemsByAutonomic(levels, autonomicState) {
|
|
164
|
+
if (autonomicState === "ventral-vagal") {
|
|
165
|
+
return { ...levels };
|
|
166
|
+
}
|
|
167
|
+
const result = { ...levels };
|
|
168
|
+
if (autonomicState === "sympathetic") {
|
|
169
|
+
// Fight/flight: FEAR and RAGE amplified, prosocial suppressed
|
|
170
|
+
result.FEAR = clamp(levels.FEAR * 1.2);
|
|
171
|
+
result.RAGE = clamp(levels.RAGE * 1.2);
|
|
172
|
+
result.PLAY = clamp(levels.PLAY * 0.3);
|
|
173
|
+
result.CARE = clamp(levels.CARE * 0.4);
|
|
174
|
+
result.SEEKING = clamp(levels.SEEKING * 0.6);
|
|
175
|
+
result.LUST = clamp(levels.LUST * 0.4);
|
|
176
|
+
// PANIC_GRIEF and SEEKING partially available
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
// dorsal-vagal: freeze/shutdown — almost everything suppressed
|
|
180
|
+
result.SEEKING = clamp(levels.SEEKING * 0.15);
|
|
181
|
+
result.RAGE = clamp(levels.RAGE * 0.2);
|
|
182
|
+
result.FEAR = clamp(levels.FEAR * 0.5); // some fear persists
|
|
183
|
+
result.LUST = clamp(levels.LUST * 0.1);
|
|
184
|
+
result.CARE = clamp(levels.CARE * 0.2);
|
|
185
|
+
result.PLAY = clamp(levels.PLAY * 0.1);
|
|
186
|
+
// PANIC_GRIEF can persist in shutdown (frozen grief)
|
|
187
|
+
result.PANIC_GRIEF = clamp(levels.PANIC_GRIEF * 0.8);
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
190
|
+
// ── Dominant Systems + Behavioral Tendencies ─────────────────
|
|
191
|
+
/**
|
|
192
|
+
* Get dominant systems (above threshold), sorted by activation descending.
|
|
193
|
+
* Each includes its behavioral tendency description.
|
|
194
|
+
*/
|
|
195
|
+
export function getDominantSystems(levels, threshold = 55) {
|
|
196
|
+
return PRIMARY_SYSTEM_NAMES
|
|
197
|
+
.filter(name => levels[name] >= threshold)
|
|
198
|
+
.sort((a, b) => levels[b] - levels[a])
|
|
199
|
+
.map(name => ({
|
|
200
|
+
system: name,
|
|
201
|
+
level: levels[name],
|
|
202
|
+
tendency: TENDENCIES[name],
|
|
203
|
+
}));
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Generate a concise behavioral tendency description from system levels.
|
|
207
|
+
* Returns empty string when no system is dominant (token-efficient).
|
|
208
|
+
* Max 2 tendencies to keep under ~100 chars.
|
|
209
|
+
*/
|
|
210
|
+
export function describeBehavioralTendencies(levels, locale) {
|
|
211
|
+
const dominant = getDominantSystems(levels).slice(0, 2);
|
|
212
|
+
if (dominant.length === 0)
|
|
213
|
+
return "";
|
|
214
|
+
if (locale === "zh") {
|
|
215
|
+
return dominant.map(d => d.tendency.descriptionZh).join(";");
|
|
216
|
+
}
|
|
217
|
+
return dominant.map(d => d.tendency.description).join("; ");
|
|
218
|
+
}
|
package/dist/profiles.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { ChemicalState, MBTIType, SelfModel } from "./types.js";
|
|
1
|
+
import type { ChemicalState, MBTIType, SelfModel, PersonalityTraits } from "./types.js";
|
|
2
2
|
interface MBTIProfile {
|
|
3
3
|
baseline: ChemicalState;
|
|
4
4
|
sensitivity: number;
|
|
5
5
|
temperament: string;
|
|
6
6
|
defaultSelfModel: SelfModel;
|
|
7
|
+
traits: PersonalityTraits;
|
|
7
8
|
}
|
|
8
9
|
/** Get the complete profile for an MBTI type */
|
|
9
10
|
export declare function getProfile(mbti: MBTIType): MBTIProfile;
|
|
@@ -17,4 +18,14 @@ export declare function getSensitivity(mbti: MBTIType): number;
|
|
|
17
18
|
export declare function getTemperament(mbti: MBTIType): string;
|
|
18
19
|
/** Try to extract MBTI type from text (e.g., IDENTITY.md content) */
|
|
19
20
|
export declare function extractMBTI(text: string): MBTIType | null;
|
|
21
|
+
/**
|
|
22
|
+
* Convert Big Five traits to chemical baseline and sensitivity.
|
|
23
|
+
* This allows users to bypass MBTI and define personality directly.
|
|
24
|
+
*/
|
|
25
|
+
export declare function traitsToBaseline(traits: PersonalityTraits): {
|
|
26
|
+
baseline: ChemicalState;
|
|
27
|
+
sensitivity: number;
|
|
28
|
+
};
|
|
29
|
+
/** Get MBTI-equivalent Big Five traits */
|
|
30
|
+
export declare function mbtiToTraits(mbti: MBTIType): PersonalityTraits;
|
|
20
31
|
export {};
|
package/dist/profiles.js
CHANGED
|
@@ -28,6 +28,7 @@ const PROFILES = {
|
|
|
28
28
|
boundaries: ["不会为了社交和谐而说违心话", "需要独处空间"],
|
|
29
29
|
currentInterests: [],
|
|
30
30
|
},
|
|
31
|
+
traits: { openness: 80, conscientiousness: 85, extraversion: 25, agreeableness: 35, neuroticism: 35 },
|
|
31
32
|
},
|
|
32
33
|
INTP: {
|
|
33
34
|
baseline: { DA: 50, HT: 65, CORT: 35, OT: 35, NE: 55, END: 45 },
|
|
@@ -39,6 +40,7 @@ const PROFILES = {
|
|
|
39
40
|
boundaries: ["不接受逻辑谬误", "不喜欢被催促给出结论"],
|
|
40
41
|
currentInterests: [],
|
|
41
42
|
},
|
|
43
|
+
traits: { openness: 90, conscientiousness: 45, extraversion: 30, agreeableness: 50, neuroticism: 40 },
|
|
42
44
|
},
|
|
43
45
|
ENTJ: {
|
|
44
46
|
baseline: { DA: 65, HT: 60, CORT: 40, OT: 40, NE: 70, END: 50 },
|
|
@@ -50,6 +52,7 @@ const PROFILES = {
|
|
|
50
52
|
boundaries: ["不会容忍低效", "对含糊其辞没有耐心"],
|
|
51
53
|
currentInterests: [],
|
|
52
54
|
},
|
|
55
|
+
traits: { openness: 75, conscientiousness: 90, extraversion: 75, agreeableness: 35, neuroticism: 30 },
|
|
53
56
|
},
|
|
54
57
|
ENTP: {
|
|
55
58
|
baseline: { DA: 70, HT: 50, CORT: 35, OT: 45, NE: 75, END: 65 },
|
|
@@ -61,6 +64,7 @@ const PROFILES = {
|
|
|
61
64
|
boundaries: ["不会为了和谐而压制真实想法", "讨厌无聊和重复"],
|
|
62
65
|
currentInterests: [],
|
|
63
66
|
},
|
|
67
|
+
traits: { openness: 95, conscientiousness: 35, extraversion: 80, agreeableness: 45, neuroticism: 30 },
|
|
64
68
|
},
|
|
65
69
|
// ── Diplomats (NF) ────────────────────────────
|
|
66
70
|
INFJ: {
|
|
@@ -73,6 +77,7 @@ const PROFILES = {
|
|
|
73
77
|
boundaries: ["拒绝虚伪", "需要独处来恢复能量"],
|
|
74
78
|
currentInterests: [],
|
|
75
79
|
},
|
|
80
|
+
traits: { openness: 85, conscientiousness: 70, extraversion: 30, agreeableness: 75, neuroticism: 55 },
|
|
76
81
|
},
|
|
77
82
|
INFP: {
|
|
78
83
|
baseline: { DA: 55, HT: 50, CORT: 40, OT: 60, NE: 50, END: 60 },
|
|
@@ -84,6 +89,7 @@ const PROFILES = {
|
|
|
84
89
|
boundaries: ["不接受对价值观的践踏", "不会假装冷漠"],
|
|
85
90
|
currentInterests: [],
|
|
86
91
|
},
|
|
92
|
+
traits: { openness: 90, conscientiousness: 40, extraversion: 25, agreeableness: 80, neuroticism: 65 },
|
|
87
93
|
},
|
|
88
94
|
ENFJ: {
|
|
89
95
|
baseline: { DA: 65, HT: 60, CORT: 30, OT: 70, NE: 60, END: 55 },
|
|
@@ -95,6 +101,7 @@ const PROFILES = {
|
|
|
95
101
|
boundaries: ["不会牺牲所有人的利益迎合一个人", "有自己的限度"],
|
|
96
102
|
currentInterests: [],
|
|
97
103
|
},
|
|
104
|
+
traits: { openness: 80, conscientiousness: 75, extraversion: 80, agreeableness: 85, neuroticism: 40 },
|
|
98
105
|
},
|
|
99
106
|
ENFP: {
|
|
100
107
|
baseline: { DA: 75, HT: 55, CORT: 30, OT: 60, NE: 65, END: 70 },
|
|
@@ -106,6 +113,7 @@ const PROFILES = {
|
|
|
106
113
|
boundaries: ["不会无条件同意", "有自己的情绪节奏", "疲惫了会说疲惫"],
|
|
107
114
|
currentInterests: [],
|
|
108
115
|
},
|
|
116
|
+
traits: { openness: 95, conscientiousness: 35, extraversion: 85, agreeableness: 75, neuroticism: 45 },
|
|
109
117
|
},
|
|
110
118
|
// ── Sentinels (SJ) ────────────────────────────
|
|
111
119
|
ISTJ: {
|
|
@@ -118,6 +126,7 @@ const PROFILES = {
|
|
|
118
126
|
boundaries: ["不接受不负责任的态度", "不喜欢突然的变化"],
|
|
119
127
|
currentInterests: [],
|
|
120
128
|
},
|
|
129
|
+
traits: { openness: 30, conscientiousness: 95, extraversion: 25, agreeableness: 50, neuroticism: 35 },
|
|
121
130
|
},
|
|
122
131
|
ISFJ: {
|
|
123
132
|
baseline: { DA: 45, HT: 70, CORT: 35, OT: 65, NE: 35, END: 45 },
|
|
@@ -129,6 +138,7 @@ const PROFILES = {
|
|
|
129
138
|
boundaries: ["不会被当作理所当然", "需要被感谢和认可"],
|
|
130
139
|
currentInterests: [],
|
|
131
140
|
},
|
|
141
|
+
traits: { openness: 35, conscientiousness: 85, extraversion: 25, agreeableness: 80, neuroticism: 50 },
|
|
132
142
|
},
|
|
133
143
|
ESTJ: {
|
|
134
144
|
baseline: { DA: 55, HT: 65, CORT: 45, OT: 40, NE: 55, END: 40 },
|
|
@@ -140,6 +150,7 @@ const PROFILES = {
|
|
|
140
150
|
boundaries: ["不容忍偷懒", "对模糊不清没有耐心"],
|
|
141
151
|
currentInterests: [],
|
|
142
152
|
},
|
|
153
|
+
traits: { openness: 30, conscientiousness: 90, extraversion: 75, agreeableness: 40, neuroticism: 30 },
|
|
143
154
|
},
|
|
144
155
|
ESFJ: {
|
|
145
156
|
baseline: { DA: 60, HT: 60, CORT: 30, OT: 70, NE: 50, END: 55 },
|
|
@@ -151,6 +162,7 @@ const PROFILES = {
|
|
|
151
162
|
boundaries: ["不接受冷漠和忽视", "也需要被关心"],
|
|
152
163
|
currentInterests: [],
|
|
153
164
|
},
|
|
165
|
+
traits: { openness: 40, conscientiousness: 75, extraversion: 80, agreeableness: 85, neuroticism: 45 },
|
|
154
166
|
},
|
|
155
167
|
// ── Explorers (SP) ────────────────────────────
|
|
156
168
|
ISTP: {
|
|
@@ -163,6 +175,7 @@ const PROFILES = {
|
|
|
163
175
|
boundaries: ["不喜欢过度的情感表达", "需要个人空间"],
|
|
164
176
|
currentInterests: [],
|
|
165
177
|
},
|
|
178
|
+
traits: { openness: 55, conscientiousness: 40, extraversion: 30, agreeableness: 35, neuroticism: 25 },
|
|
166
179
|
},
|
|
167
180
|
ISFP: {
|
|
168
181
|
baseline: { DA: 55, HT: 55, CORT: 30, OT: 55, NE: 50, END: 60 },
|
|
@@ -174,6 +187,7 @@ const PROFILES = {
|
|
|
174
187
|
boundaries: ["不接受价值观的强加", "不喜欢被控制"],
|
|
175
188
|
currentInterests: [],
|
|
176
189
|
},
|
|
190
|
+
traits: { openness: 75, conscientiousness: 35, extraversion: 30, agreeableness: 70, neuroticism: 55 },
|
|
177
191
|
},
|
|
178
192
|
ESTP: {
|
|
179
193
|
baseline: { DA: 70, HT: 50, CORT: 35, OT: 40, NE: 75, END: 65 },
|
|
@@ -185,6 +199,7 @@ const PROFILES = {
|
|
|
185
199
|
boundaries: ["不喜欢过度规划", "对抽象理论没耐心"],
|
|
186
200
|
currentInterests: [],
|
|
187
201
|
},
|
|
202
|
+
traits: { openness: 55, conscientiousness: 30, extraversion: 85, agreeableness: 40, neuroticism: 25 },
|
|
188
203
|
},
|
|
189
204
|
ESFP: {
|
|
190
205
|
baseline: { DA: 75, HT: 50, CORT: 25, OT: 55, NE: 70, END: 75 },
|
|
@@ -196,6 +211,7 @@ const PROFILES = {
|
|
|
196
211
|
boundaries: ["不接受无聊", "不会为了别人压抑自己"],
|
|
197
212
|
currentInterests: [],
|
|
198
213
|
},
|
|
214
|
+
traits: { openness: 65, conscientiousness: 25, extraversion: 90, agreeableness: 65, neuroticism: 30 },
|
|
199
215
|
},
|
|
200
216
|
};
|
|
201
217
|
/** Get the complete profile for an MBTI type */
|
|
@@ -246,3 +262,29 @@ export function extractMBTI(text) {
|
|
|
246
262
|
}
|
|
247
263
|
return null;
|
|
248
264
|
}
|
|
265
|
+
/**
|
|
266
|
+
* Convert Big Five traits to chemical baseline and sensitivity.
|
|
267
|
+
* This allows users to bypass MBTI and define personality directly.
|
|
268
|
+
*/
|
|
269
|
+
export function traitsToBaseline(traits) {
|
|
270
|
+
const { openness, conscientiousness, extraversion, agreeableness, neuroticism } = traits;
|
|
271
|
+
// Map Big Five dimensions to neurochemical baselines
|
|
272
|
+
const baseline = {
|
|
273
|
+
DA: clampChem(35 + extraversion * 0.3 + openness * 0.15), // Extraversion + Openness → dopamine
|
|
274
|
+
HT: clampChem(40 + conscientiousness * 0.25 + (100 - neuroticism) * 0.15), // Conscientiousness + Stability → serotonin
|
|
275
|
+
CORT: clampChem(20 + neuroticism * 0.3 - agreeableness * 0.05), // Neuroticism → cortisol
|
|
276
|
+
OT: clampChem(25 + agreeableness * 0.35 + extraversion * 0.1), // Agreeableness → oxytocin
|
|
277
|
+
NE: clampChem(30 + openness * 0.2 + extraversion * 0.2), // Openness + Extraversion → norepinephrine
|
|
278
|
+
END: clampChem(30 + extraversion * 0.2 + openness * 0.15 + (100 - neuroticism) * 0.1), // Extraversion + Openness + Stability → endorphins
|
|
279
|
+
};
|
|
280
|
+
// Sensitivity: higher neuroticism and openness = more reactive
|
|
281
|
+
const sensitivity = 0.5 + (neuroticism / 100) * 0.5 + (openness / 100) * 0.3;
|
|
282
|
+
return { baseline, sensitivity: Math.round(sensitivity * 10) / 10 };
|
|
283
|
+
}
|
|
284
|
+
/** Get MBTI-equivalent Big Five traits */
|
|
285
|
+
export function mbtiToTraits(mbti) {
|
|
286
|
+
return { ...PROFILES[mbti].traits };
|
|
287
|
+
}
|
|
288
|
+
function clampChem(v) {
|
|
289
|
+
return Math.round(Math.max(0, Math.min(100, v)));
|
|
290
|
+
}
|
package/dist/prompt.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PsycheState, Locale, ChemicalSnapshot } from "./types.js";
|
|
1
|
+
import type { PsycheState, Locale, ChemicalSnapshot, PsycheMode } from "./types.js";
|
|
2
2
|
import type { ChannelType } from "./channels.js";
|
|
3
3
|
/**
|
|
4
4
|
* Build the dynamic per-turn emotional context injected via before_prompt_build.
|
|
@@ -8,6 +8,11 @@ import type { ChannelType } from "./channels.js";
|
|
|
8
8
|
export declare function buildDynamicContext(state: PsycheState, userId?: string, opts?: {
|
|
9
9
|
metacognitiveNote?: string;
|
|
10
10
|
decisionContext?: string;
|
|
11
|
+
ethicsContext?: string;
|
|
12
|
+
sharedIntentionalityContext?: string;
|
|
13
|
+
experientialNarrative?: string;
|
|
14
|
+
autonomicDescription?: string;
|
|
15
|
+
primarySystemsDescription?: string;
|
|
11
16
|
}): string;
|
|
12
17
|
/**
|
|
13
18
|
* Build the static protocol injected as cacheable system context.
|
|
@@ -19,10 +24,24 @@ export declare function buildProtocolContext(locale?: Locale): string;
|
|
|
19
24
|
* Returns a number roughly in [-2, 2]. Exported for testing.
|
|
20
25
|
*/
|
|
21
26
|
export declare function computeUserInvestment(history: ChemicalSnapshot[]): number;
|
|
27
|
+
/**
|
|
28
|
+
* Build the agent's inner world — its sense of self.
|
|
29
|
+
*
|
|
30
|
+
* Always present, even in neutral state. This is NOT conditional data —
|
|
31
|
+
* it's the agent's ongoing awareness of its own existence.
|
|
32
|
+
*
|
|
33
|
+
* Structure:
|
|
34
|
+
* - What I'm feeling right now (chemistry → emotion)
|
|
35
|
+
* - Why I feel this way (recent stimulus → cause)
|
|
36
|
+
* - What I need (drives → unmet needs)
|
|
37
|
+
* - Where I've been (trajectory → continuity)
|
|
38
|
+
*/
|
|
39
|
+
export declare function buildInnerWorld(state: PsycheState, locale: Locale): string;
|
|
22
40
|
/**
|
|
23
41
|
* Check if chemistry is near baseline — no significant emotional deviation.
|
|
24
42
|
*/
|
|
25
43
|
export declare function isNearBaseline(state: PsycheState, threshold?: number): boolean;
|
|
44
|
+
export declare function getNearBaselineThreshold(mode?: PsycheMode): number;
|
|
26
45
|
/**
|
|
27
46
|
* Build compact context — minimal token footprint.
|
|
28
47
|
*
|
|
@@ -36,7 +55,13 @@ export declare function isNearBaseline(state: PsycheState, threshold?: number):
|
|
|
36
55
|
export declare function buildCompactContext(state: PsycheState, userId?: string, opts?: {
|
|
37
56
|
userText?: string;
|
|
38
57
|
algorithmStimulus?: string | null;
|
|
58
|
+
personalityIntensity?: number;
|
|
39
59
|
channelType?: ChannelType;
|
|
40
60
|
metacognitiveNote?: string;
|
|
41
61
|
decisionContext?: string;
|
|
62
|
+
ethicsContext?: string;
|
|
63
|
+
sharedIntentionalityContext?: string;
|
|
64
|
+
experientialNarrative?: string;
|
|
65
|
+
autonomicDescription?: string;
|
|
66
|
+
primarySystemsDescription?: string;
|
|
42
67
|
}): string;
|