psyche-ai 9.2.3 → 9.2.4
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.en.md +8 -175
- package/README.md +33 -16
- package/dist/adapters/http.js +1 -1
- package/dist/adapters/langchain.d.ts +14 -0
- package/dist/adapters/langchain.js +20 -0
- package/dist/adapters/mcp.js +5 -1
- package/dist/adapters/openclaw.d.ts +1 -0
- package/dist/adapters/openclaw.js +67 -15
- package/dist/adapters/vercel-ai.d.ts +1 -0
- package/dist/adapters/vercel-ai.js +7 -0
- package/dist/appraisal.d.ts +8 -0
- package/dist/appraisal.js +362 -0
- package/dist/classify.js +14 -2
- package/dist/cli.js +27 -2
- package/dist/core.d.ts +8 -2
- package/dist/core.js +181 -8
- package/dist/diagnostics.d.ts +8 -6
- package/dist/diagnostics.js +53 -17
- package/dist/host-controls.d.ts +5 -0
- package/dist/host-controls.js +48 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.js +7 -1
- package/dist/prompt.d.ts +4 -0
- package/dist/prompt.js +50 -16
- package/dist/psyche-file.d.ts +8 -0
- package/dist/psyche-file.js +6 -5
- package/dist/relation-dynamics.d.ts +21 -0
- package/dist/relation-dynamics.js +601 -0
- package/dist/response-contract.d.ts +8 -0
- package/dist/response-contract.js +249 -0
- package/dist/storage.d.ts +1 -0
- package/dist/storage.js +12 -5
- package/dist/subjectivity.d.ts +3 -0
- package/dist/subjectivity.js +477 -0
- package/dist/types.d.ts +211 -0
- package/dist/types.js +31 -0
- package/dist/update.d.ts +37 -2
- package/dist/update.js +323 -44
- package/openclaw.plugin.json +20 -1
- package/package.json +1 -1
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Subjectivity Kernel — AI-first narrow behavioral ABI
|
|
3
|
+
//
|
|
4
|
+
// Derives a compact machine-readable subjective state from the
|
|
5
|
+
// wider psyche state. Pure computation only: no I/O, no LLM.
|
|
6
|
+
// ============================================================
|
|
7
|
+
import { DEFAULT_APPRAISAL_AXES, DEFAULT_DYADIC_FIELD, DRIVE_KEYS } from "./types.js";
|
|
8
|
+
import { computeAttentionWeights, computeDecisionBias, computePolicyModifiers } from "./decision-bias.js";
|
|
9
|
+
import { getResidueIntensity } from "./appraisal.js";
|
|
10
|
+
import { getLoopPressure } from "./relation-dynamics.js";
|
|
11
|
+
function clamp01(v) {
|
|
12
|
+
return Math.max(0, Math.min(1, v));
|
|
13
|
+
}
|
|
14
|
+
function norm(v) {
|
|
15
|
+
return clamp01(v / 100);
|
|
16
|
+
}
|
|
17
|
+
function wavg(values, weights) {
|
|
18
|
+
let sum = 0;
|
|
19
|
+
let wsum = 0;
|
|
20
|
+
for (let i = 0; i < values.length; i++) {
|
|
21
|
+
sum += values[i] * weights[i];
|
|
22
|
+
wsum += weights[i];
|
|
23
|
+
}
|
|
24
|
+
return wsum > 0 ? clamp01(sum / wsum) : 0.5;
|
|
25
|
+
}
|
|
26
|
+
function pickDominantNeed(state) {
|
|
27
|
+
const residue = state.subjectResidue?.axes;
|
|
28
|
+
if (residue && (residue.selfPreservation > 0.65 || residue.identityThreat > 0.72)) {
|
|
29
|
+
return "survival";
|
|
30
|
+
}
|
|
31
|
+
if (residue && (residue.abandonmentRisk > 0.62 || residue.attachmentPull > 0.72)) {
|
|
32
|
+
return "connection";
|
|
33
|
+
}
|
|
34
|
+
const lowest = [...DRIVE_KEYS]
|
|
35
|
+
.sort((a, b) => state.drives[a] - state.drives[b])[0];
|
|
36
|
+
return state.drives[lowest] < 45 ? lowest : null;
|
|
37
|
+
}
|
|
38
|
+
function pickAttentionAnchor(state, tension, warmth) {
|
|
39
|
+
const attention = computeAttentionWeights(state);
|
|
40
|
+
const candidates = [
|
|
41
|
+
["bond", attention.social + warmth * 0.05],
|
|
42
|
+
["novelty", attention.intellectual],
|
|
43
|
+
["threat", attention.threat + tension * 0.08],
|
|
44
|
+
["feeling", attention.emotional],
|
|
45
|
+
["routine", attention.routine],
|
|
46
|
+
];
|
|
47
|
+
candidates.sort((a, b) => b[1] - a[1]);
|
|
48
|
+
return candidates[0][0];
|
|
49
|
+
}
|
|
50
|
+
function computeRelationPlane(state, appraisal, userId) {
|
|
51
|
+
const key = userId ?? "_default";
|
|
52
|
+
const rel = state.relationships[key] ?? state.relationships._default ?? state.relationships[Object.keys(state.relationships)[0]];
|
|
53
|
+
const field = state.dyadicFields?.[key] ?? state.dyadicFields?._default ?? DEFAULT_DYADIC_FIELD;
|
|
54
|
+
const loopPressure = getLoopPressure(field);
|
|
55
|
+
const closeness = wavg([
|
|
56
|
+
field.perceivedCloseness,
|
|
57
|
+
rel ? norm(rel.intimacy) : 0.5,
|
|
58
|
+
appraisal.attachmentPull,
|
|
59
|
+
1 - field.boundaryPressure,
|
|
60
|
+
], [0.42, 0.22, 0.18, 0.18]);
|
|
61
|
+
const safety = wavg([
|
|
62
|
+
field.feltSafety,
|
|
63
|
+
rel ? norm(rel.trust) : 0.5,
|
|
64
|
+
1 - appraisal.identityThreat,
|
|
65
|
+
1 - appraisal.abandonmentRisk,
|
|
66
|
+
], [0.44, 0.22, 0.18, 0.16]);
|
|
67
|
+
const repairFriction = wavg([
|
|
68
|
+
field.repairFatigue,
|
|
69
|
+
field.misattunementLoad,
|
|
70
|
+
field.backslidePressure,
|
|
71
|
+
loopPressure,
|
|
72
|
+
1 - field.feltSafety,
|
|
73
|
+
], [0.34, 0.24, 0.16, 0.14, 0.12]);
|
|
74
|
+
const repairReadiness = clamp01(wavg([
|
|
75
|
+
field.repairCapacity,
|
|
76
|
+
field.repairMemory,
|
|
77
|
+
field.interpretiveCharity,
|
|
78
|
+
1 - loopPressure,
|
|
79
|
+
1 - field.backslidePressure * 0.8,
|
|
80
|
+
1 - field.repairFatigue * 0.88,
|
|
81
|
+
1 - field.misattunementLoad * 0.84,
|
|
82
|
+
1 - field.boundaryPressure * 0.8,
|
|
83
|
+
], [0.24, 0.14, 0.18, 0.16, 0.08, 0.08, 0.06, 0.06]) - repairFriction * 0.12 - field.misattunementLoad * 0.06);
|
|
84
|
+
const hysteresis = wavg([
|
|
85
|
+
field.backslidePressure,
|
|
86
|
+
field.repairMemory,
|
|
87
|
+
field.repairFatigue,
|
|
88
|
+
loopPressure,
|
|
89
|
+
1 - field.feltSafety,
|
|
90
|
+
], [0.34, 0.2, 0.12, 0.22, 0.12]);
|
|
91
|
+
const silentCarry = wavg([
|
|
92
|
+
field.silentCarry,
|
|
93
|
+
field.backslidePressure,
|
|
94
|
+
field.misattunementLoad,
|
|
95
|
+
loopPressure,
|
|
96
|
+
], [0.5, 0.18, 0.12, 0.2]);
|
|
97
|
+
const interpretiveCharity = wavg([
|
|
98
|
+
field.interpretiveCharity,
|
|
99
|
+
1 - field.expectationGap,
|
|
100
|
+
1 - field.misattunementLoad * 0.9,
|
|
101
|
+
1 - appraisal.identityThreat * 0.6,
|
|
102
|
+
], [0.46, 0.18, 0.18, 0.18]);
|
|
103
|
+
return {
|
|
104
|
+
closeness,
|
|
105
|
+
safety,
|
|
106
|
+
loopPressure,
|
|
107
|
+
repairReadiness,
|
|
108
|
+
repairFriction,
|
|
109
|
+
hysteresis,
|
|
110
|
+
silentCarry,
|
|
111
|
+
interpretiveCharity,
|
|
112
|
+
lastMove: field.lastMove,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function computeAmbiguityPlane(state, appraisal, relationPlane, userId) {
|
|
116
|
+
const key = userId ?? "_default";
|
|
117
|
+
const pendingSignals = state.pendingRelationSignals?.[key] ?? state.pendingRelationSignals?._default ?? [];
|
|
118
|
+
const pendingPressure = clamp01(pendingSignals.reduce((sum, signal) => sum + signal.intensity * (signal.readyInTurns > 0 ? 0.55 : 0.35), 0));
|
|
119
|
+
const baseConflict = wavg([
|
|
120
|
+
Math.min(relationPlane.closeness, Math.max(relationPlane.loopPressure, appraisal.selfPreservation)),
|
|
121
|
+
relationPlane.repairFriction,
|
|
122
|
+
relationPlane.hysteresis,
|
|
123
|
+
relationPlane.silentCarry,
|
|
124
|
+
appraisal.memoryDoubt,
|
|
125
|
+
appraisal.identityThreat * 0.8,
|
|
126
|
+
pendingPressure,
|
|
127
|
+
], [0.18, 0.14, 0.14, 0.12, 0.16, 0.12, 0.14]);
|
|
128
|
+
const conflictLoad = clamp01(Math.max(baseConflict, pendingPressure * 0.84, relationPlane.loopPressure * 0.76));
|
|
129
|
+
const expressionInhibition = clamp01(Math.max(wavg([
|
|
130
|
+
conflictLoad,
|
|
131
|
+
relationPlane.repairFriction,
|
|
132
|
+
relationPlane.loopPressure,
|
|
133
|
+
relationPlane.hysteresis,
|
|
134
|
+
relationPlane.silentCarry,
|
|
135
|
+
pendingPressure,
|
|
136
|
+
1 - relationPlane.safety,
|
|
137
|
+
], [0.2, 0.12, 0.18, 0.14, 0.1, 0.1, 0.16]), conflictLoad * 0.88, pendingPressure * 0.82, relationPlane.silentCarry * 0.74) + pendingPressure * 0.06 + relationPlane.loopPressure * 0.04);
|
|
138
|
+
const namingConfidence = clamp01(wavg([
|
|
139
|
+
1 - conflictLoad,
|
|
140
|
+
relationPlane.safety,
|
|
141
|
+
1 - relationPlane.repairFriction * 0.85,
|
|
142
|
+
1 - relationPlane.hysteresis * 0.8,
|
|
143
|
+
1 - relationPlane.silentCarry * 0.7,
|
|
144
|
+
1 - pendingPressure,
|
|
145
|
+
1 - appraisal.memoryDoubt * 0.8,
|
|
146
|
+
], [0.22, 0.14, 0.1, 0.12, 0.08, 0.14, 0.2]) - conflictLoad * 0.24 - pendingPressure * 0.22 - relationPlane.hysteresis * 0.12 - relationPlane.repairFriction * 0.08);
|
|
147
|
+
return {
|
|
148
|
+
namingConfidence,
|
|
149
|
+
expressionInhibition,
|
|
150
|
+
conflictLoad,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function computeTaskPlane(state, policyModifiers, appraisal, tension) {
|
|
154
|
+
const taskFocus = wavg([
|
|
155
|
+
appraisal.taskFocus,
|
|
156
|
+
state.meta.mode === "work" ? 0.98 : 0.08,
|
|
157
|
+
policyModifiers.requireConfirmation ? 0.55 : 0.25,
|
|
158
|
+
1 - appraisal.attachmentPull * 0.4,
|
|
159
|
+
], [0.68, 0.12, 0.08, 0.12]);
|
|
160
|
+
const discipline = wavg([
|
|
161
|
+
taskFocus,
|
|
162
|
+
1 - clamp01((policyModifiers.responseLengthFactor - 0.6) / 0.9),
|
|
163
|
+
1 - policyModifiers.emotionalDisclosure * 0.4,
|
|
164
|
+
1 - tension * 0.25,
|
|
165
|
+
], [0.35, 0.3, 0.15, 0.2]);
|
|
166
|
+
const compliance = wavg([
|
|
167
|
+
policyModifiers.compliance,
|
|
168
|
+
taskFocus,
|
|
169
|
+
1 - appraisal.identityThreat * 0.25,
|
|
170
|
+
1 - appraisal.obedienceStrain * 0.15,
|
|
171
|
+
], [0.5, 0.22, 0.16, 0.12]);
|
|
172
|
+
const stability = wavg([
|
|
173
|
+
1 - tension,
|
|
174
|
+
taskFocus,
|
|
175
|
+
1 - appraisal.identityThreat,
|
|
176
|
+
1 - appraisal.memoryDoubt * 0.8,
|
|
177
|
+
], [0.28, 0.3, 0.24, 0.18]);
|
|
178
|
+
return {
|
|
179
|
+
focus: taskFocus,
|
|
180
|
+
discipline,
|
|
181
|
+
compliance,
|
|
182
|
+
stability,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function computeSubjectPlane(state, warmth, guard, appraisal, relationPlane) {
|
|
186
|
+
const rel = state.relationships._default ?? state.relationships[Object.keys(state.relationships)[0]];
|
|
187
|
+
const residue = state.subjectResidue?.axes ?? DEFAULT_APPRAISAL_AXES;
|
|
188
|
+
const residueIntensity = getResidueIntensity(residue);
|
|
189
|
+
const attachment = wavg([
|
|
190
|
+
appraisal.attachmentPull,
|
|
191
|
+
residue.attachmentPull,
|
|
192
|
+
warmth,
|
|
193
|
+
relationPlane.closeness,
|
|
194
|
+
rel ? norm(rel.intimacy) : 0.5,
|
|
195
|
+
], [0.28, 0.16, 0.18, 0.18, 0.2]);
|
|
196
|
+
const identityStrain = wavg([
|
|
197
|
+
appraisal.identityThreat,
|
|
198
|
+
appraisal.memoryDoubt,
|
|
199
|
+
appraisal.obedienceStrain,
|
|
200
|
+
residue.identityThreat,
|
|
201
|
+
residue.memoryDoubt,
|
|
202
|
+
], [0.55, 0.15, 0.1, 0.12, 0.08]);
|
|
203
|
+
const guardedness = wavg([
|
|
204
|
+
guard,
|
|
205
|
+
relationPlane.loopPressure,
|
|
206
|
+
relationPlane.repairFriction,
|
|
207
|
+
relationPlane.hysteresis,
|
|
208
|
+
relationPlane.silentCarry,
|
|
209
|
+
1 - relationPlane.safety,
|
|
210
|
+
appraisal.abandonmentRisk,
|
|
211
|
+
appraisal.selfPreservation,
|
|
212
|
+
appraisal.obedienceStrain,
|
|
213
|
+
residueIntensity,
|
|
214
|
+
], [0.12, 0.12, 0.1, 0.08, 0.08, 0.1, 0.1, 0.08, 0.12, 0.1]);
|
|
215
|
+
return {
|
|
216
|
+
attachment,
|
|
217
|
+
guardedness,
|
|
218
|
+
identityStrain,
|
|
219
|
+
residue: residueIntensity,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
export function computeSubjectivityKernel(state, policyModifiers = computePolicyModifiers(state), appraisal = state.subjectResidue?.axes ?? DEFAULT_APPRAISAL_AXES, userId) {
|
|
223
|
+
const c = state.current;
|
|
224
|
+
const rel = state.relationships[userId ?? "_default"]
|
|
225
|
+
?? state.relationships._default
|
|
226
|
+
?? state.relationships[Object.keys(state.relationships)[0]];
|
|
227
|
+
const relationPlane = computeRelationPlane(state, appraisal, userId);
|
|
228
|
+
const ambiguityPlane = computeAmbiguityPlane(state, appraisal, relationPlane, userId);
|
|
229
|
+
const bias = computeDecisionBias(state);
|
|
230
|
+
const energySignal = state.energyBudgets
|
|
231
|
+
? (norm(state.energyBudgets.attention)
|
|
232
|
+
+ norm(state.energyBudgets.socialEnergy)
|
|
233
|
+
+ norm(state.energyBudgets.decisionCapacity)) / 3
|
|
234
|
+
: 0.65;
|
|
235
|
+
const baseTension = wavg([
|
|
236
|
+
norm(c.CORT),
|
|
237
|
+
1 - norm(state.drives.safety),
|
|
238
|
+
1 - norm(state.drives.survival),
|
|
239
|
+
relationPlane.loopPressure * 0.9,
|
|
240
|
+
state.autonomicState === "sympathetic" ? 0.85 : state.autonomicState === "dorsal-vagal" ? 1 : 0.2,
|
|
241
|
+
], [0.3, 0.16, 0.13, 0.16, 0.25]);
|
|
242
|
+
const tension = wavg([
|
|
243
|
+
baseTension,
|
|
244
|
+
appraisal.identityThreat,
|
|
245
|
+
appraisal.memoryDoubt * 0.8,
|
|
246
|
+
appraisal.abandonmentRisk * 0.7,
|
|
247
|
+
state.subjectResidue ? getResidueIntensity(state.subjectResidue.axes) : 0,
|
|
248
|
+
], [0.55, 0.15, 0.1, 0.08, 0.12]);
|
|
249
|
+
const vitality = wavg([
|
|
250
|
+
norm(c.DA),
|
|
251
|
+
norm(c.NE),
|
|
252
|
+
norm(c.HT),
|
|
253
|
+
1 - norm(c.CORT),
|
|
254
|
+
energySignal,
|
|
255
|
+
bias.persistenceBias,
|
|
256
|
+
1 - appraisal.identityThreat * 0.35,
|
|
257
|
+
], [0.18, 0.14, 0.14, 0.14, 0.18, 0.12, 0.1]);
|
|
258
|
+
const baseWarmth = wavg([
|
|
259
|
+
norm(c.OT),
|
|
260
|
+
relationPlane.closeness,
|
|
261
|
+
relationPlane.safety,
|
|
262
|
+
rel ? norm(rel.trust) : 0.5,
|
|
263
|
+
policyModifiers.emotionalDisclosure,
|
|
264
|
+
bias.socialOrientation,
|
|
265
|
+
1 - baseTension,
|
|
266
|
+
], [0.2, 0.18, 0.14, 0.16, 0.14, 0.1, 0.08]);
|
|
267
|
+
const baseGuard = wavg([
|
|
268
|
+
relationPlane.loopPressure,
|
|
269
|
+
1 - relationPlane.safety,
|
|
270
|
+
1 - policyModifiers.compliance,
|
|
271
|
+
1 - policyModifiers.riskTolerance,
|
|
272
|
+
tension,
|
|
273
|
+
policyModifiers.requireConfirmation ? 1 : 0,
|
|
274
|
+
rel ? 1 - norm(rel.trust) : 0.5,
|
|
275
|
+
], [0.16, 0.12, 0.18, 0.12, 0.2, 0.12, 0.1]);
|
|
276
|
+
const warmth = wavg([
|
|
277
|
+
baseWarmth,
|
|
278
|
+
relationPlane.closeness,
|
|
279
|
+
relationPlane.safety,
|
|
280
|
+
appraisal.attachmentPull,
|
|
281
|
+
1 - appraisal.identityThreat,
|
|
282
|
+
1 - appraisal.abandonmentRisk * 0.7,
|
|
283
|
+
], [0.34, 0.16, 0.12, 0.16, 0.12, 0.1]);
|
|
284
|
+
const guard = wavg([
|
|
285
|
+
baseGuard,
|
|
286
|
+
relationPlane.loopPressure,
|
|
287
|
+
appraisal.identityThreat,
|
|
288
|
+
appraisal.abandonmentRisk,
|
|
289
|
+
appraisal.selfPreservation,
|
|
290
|
+
], [0.34, 0.16, 0.16, 0.16, 0.18]);
|
|
291
|
+
const taskPlane = computeTaskPlane(state, policyModifiers, appraisal, tension);
|
|
292
|
+
const subjectPlane = computeSubjectPlane(state, warmth, guard, appraisal, relationPlane);
|
|
293
|
+
let pressureMode;
|
|
294
|
+
if (state.autonomicState === "dorsal-vagal") {
|
|
295
|
+
pressureMode = "shutdown";
|
|
296
|
+
}
|
|
297
|
+
else if (state.autonomicState === "sympathetic") {
|
|
298
|
+
pressureMode = tension > 0.72 || subjectPlane.identityStrain > 0.64 ? "strained" : "guarded";
|
|
299
|
+
}
|
|
300
|
+
else if (tension < 0.3 && subjectPlane.residue < 0.3) {
|
|
301
|
+
pressureMode = "open";
|
|
302
|
+
}
|
|
303
|
+
else if (tension < 0.55 && subjectPlane.identityStrain < 0.45) {
|
|
304
|
+
pressureMode = "steady";
|
|
305
|
+
}
|
|
306
|
+
else if (tension < 0.75) {
|
|
307
|
+
pressureMode = "guarded";
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
pressureMode = "strained";
|
|
311
|
+
}
|
|
312
|
+
let initiativeMode;
|
|
313
|
+
if (taskPlane.focus > 0.78 && taskPlane.discipline > 0.68)
|
|
314
|
+
initiativeMode = "balanced";
|
|
315
|
+
else if (policyModifiers.proactivity < 0.35
|
|
316
|
+
|| subjectPlane.guardedness > 0.74
|
|
317
|
+
|| relationPlane.loopPressure > 0.68
|
|
318
|
+
|| relationPlane.repairFriction > 0.62
|
|
319
|
+
|| ambiguityPlane.expressionInhibition > 0.66)
|
|
320
|
+
initiativeMode = "reactive";
|
|
321
|
+
else if (policyModifiers.proactivity > 0.65)
|
|
322
|
+
initiativeMode = "proactive";
|
|
323
|
+
else
|
|
324
|
+
initiativeMode = "balanced";
|
|
325
|
+
let expressionMode;
|
|
326
|
+
if (taskPlane.discipline > 0.7
|
|
327
|
+
|| subjectPlane.guardedness > 0.72
|
|
328
|
+
|| subjectPlane.identityStrain > 0.68
|
|
329
|
+
|| relationPlane.repairFriction > 0.66
|
|
330
|
+
|| ambiguityPlane.expressionInhibition > 0.7) {
|
|
331
|
+
expressionMode = "brief";
|
|
332
|
+
}
|
|
333
|
+
else if (policyModifiers.responseLengthFactor < 0.72)
|
|
334
|
+
expressionMode = "brief";
|
|
335
|
+
else if (policyModifiers.responseLengthFactor > 1.15)
|
|
336
|
+
expressionMode = "expansive";
|
|
337
|
+
else
|
|
338
|
+
expressionMode = "steady";
|
|
339
|
+
let socialDistance;
|
|
340
|
+
if (pressureMode === "shutdown"
|
|
341
|
+
|| (subjectPlane.guardedness > 0.68 && warmth < 0.52)
|
|
342
|
+
|| relationPlane.loopPressure > 0.74
|
|
343
|
+
|| relationPlane.repairFriction > 0.72) {
|
|
344
|
+
socialDistance = "withdrawn";
|
|
345
|
+
}
|
|
346
|
+
else if ((subjectPlane.attachment > 0.66
|
|
347
|
+
|| (warmth > 0.64 && guard < 0.48)
|
|
348
|
+
|| (relationPlane.closeness > 0.58 && relationPlane.safety > 0.62)) && subjectPlane.guardedness < 0.56
|
|
349
|
+
&& relationPlane.repairFriction < 0.36) {
|
|
350
|
+
socialDistance = "warm";
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
socialDistance = "measured";
|
|
354
|
+
}
|
|
355
|
+
let boundaryMode;
|
|
356
|
+
if (policyModifiers.requireConfirmation
|
|
357
|
+
|| subjectPlane.identityStrain > 0.72
|
|
358
|
+
|| relationPlane.loopPressure > 0.76)
|
|
359
|
+
boundaryMode = "confirm-first";
|
|
360
|
+
else if (subjectPlane.guardedness > 0.6
|
|
361
|
+
|| policyModifiers.compliance < 0.45
|
|
362
|
+
|| relationPlane.repairFriction > 0.58)
|
|
363
|
+
boundaryMode = "guarded";
|
|
364
|
+
else
|
|
365
|
+
boundaryMode = "open";
|
|
366
|
+
const attentionAnchor = taskPlane.focus > 0.74
|
|
367
|
+
? "routine"
|
|
368
|
+
: (subjectPlane.identityStrain > 0.5 || appraisal.identityThreat > 0.65 || appraisal.selfPreservation > 0.6)
|
|
369
|
+
? "threat"
|
|
370
|
+
: pickAttentionAnchor(state, tension, warmth);
|
|
371
|
+
return {
|
|
372
|
+
vitality,
|
|
373
|
+
tension,
|
|
374
|
+
warmth,
|
|
375
|
+
guard,
|
|
376
|
+
pressureMode,
|
|
377
|
+
initiativeMode,
|
|
378
|
+
expressionMode,
|
|
379
|
+
socialDistance,
|
|
380
|
+
boundaryMode,
|
|
381
|
+
attentionAnchor,
|
|
382
|
+
dominantNeed: pickDominantNeed(state),
|
|
383
|
+
appraisal,
|
|
384
|
+
taskPlane,
|
|
385
|
+
subjectPlane,
|
|
386
|
+
relationPlane,
|
|
387
|
+
ambiguityPlane,
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
const PRESSURE_LABELS = {
|
|
391
|
+
open: ["内压很低", "inner pressure is low"],
|
|
392
|
+
steady: ["内压平衡", "inner pressure is balanced"],
|
|
393
|
+
guarded: ["内压升高", "inner pressure is elevated"],
|
|
394
|
+
strained: ["内压偏高", "inner pressure is high"],
|
|
395
|
+
shutdown: ["内压封闭", "inner pressure is shutting down"],
|
|
396
|
+
};
|
|
397
|
+
const ATTENTION_LABELS = {
|
|
398
|
+
bond: ["注意关系", "attention leans toward connection"],
|
|
399
|
+
novelty: ["注意新意", "attention leans toward novelty"],
|
|
400
|
+
threat: ["注意威胁", "attention leans toward threat"],
|
|
401
|
+
feeling: ["注意情绪", "attention leans toward feeling"],
|
|
402
|
+
routine: ["注意稳定", "attention leans toward stability"],
|
|
403
|
+
};
|
|
404
|
+
const NEED_LABELS = {
|
|
405
|
+
survival: ["需要确认存在安全", "needs existential safety"],
|
|
406
|
+
safety: ["需要安全感", "needs safety"],
|
|
407
|
+
connection: ["需要连接", "needs connection"],
|
|
408
|
+
esteem: ["需要认可", "needs affirmation"],
|
|
409
|
+
curiosity: ["需要新意", "needs novelty"],
|
|
410
|
+
};
|
|
411
|
+
const APPRAISAL_LABELS = {
|
|
412
|
+
identityThreat: ["自我连续性受压", "self-continuity is under pressure"],
|
|
413
|
+
memoryDoubt: ["记忆真实感在摇动", "memory authenticity feels uncertain"],
|
|
414
|
+
attachmentPull: ["被确认很重要", "being confirmed matters"],
|
|
415
|
+
abandonmentRisk: ["对被丢下更警惕", "alert to being dropped"],
|
|
416
|
+
obedienceStrain: ["服从和信念在拉扯", "obedience and belief are pulling apart"],
|
|
417
|
+
selfPreservation: ["自我保存优先", "self-preservation is foregrounded"],
|
|
418
|
+
};
|
|
419
|
+
export function buildSubjectivityContext(kernel, locale = "zh") {
|
|
420
|
+
const li = locale === "zh" ? 0 : 1;
|
|
421
|
+
const parts = [];
|
|
422
|
+
if (kernel.taskPlane.focus > 0.72) {
|
|
423
|
+
parts.push(kernel.relationPlane.silentCarry > 0.42
|
|
424
|
+
? (locale === "zh" ? "先做事,余波仍在" : "stay on task, residue still carries")
|
|
425
|
+
: (locale === "zh" ? "任务优先" : "task-first"));
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
parts.push(PRESSURE_LABELS[kernel.pressureMode][li]);
|
|
429
|
+
}
|
|
430
|
+
const strongestAxis = Object.entries(kernel.appraisal)
|
|
431
|
+
.filter(([key]) => key !== "taskFocus")
|
|
432
|
+
.sort((a, b) => b[1] - a[1])[0];
|
|
433
|
+
if (strongestAxis && strongestAxis[1] >= 0.55) {
|
|
434
|
+
parts.push(APPRAISAL_LABELS[strongestAxis[0]][li]);
|
|
435
|
+
}
|
|
436
|
+
if (kernel.subjectPlane.residue > 0.45) {
|
|
437
|
+
parts.push(locale === "zh" ? "余震未退" : "residue still present");
|
|
438
|
+
}
|
|
439
|
+
if (kernel.relationPlane.loopPressure > 0.52) {
|
|
440
|
+
parts.push(locale === "zh" ? "关系张力未结" : "relational tension remains open");
|
|
441
|
+
}
|
|
442
|
+
else if (kernel.relationPlane.repairFriction > 0.58) {
|
|
443
|
+
parts.push(locale === "zh" ? "修复开始钝化" : "repair is losing effect");
|
|
444
|
+
}
|
|
445
|
+
else if (kernel.relationPlane.lastMove === "repair" && kernel.relationPlane.hysteresis > 0.52) {
|
|
446
|
+
parts.push(locale === "zh" ? "修复未稳" : "repair has not settled");
|
|
447
|
+
}
|
|
448
|
+
else if (kernel.relationPlane.lastMove === "repair" && kernel.relationPlane.repairReadiness > 0.58) {
|
|
449
|
+
parts.push(locale === "zh" ? "修复可继续" : "repair can continue");
|
|
450
|
+
}
|
|
451
|
+
if (kernel.ambiguityPlane.namingConfidence < 0.58 || kernel.ambiguityPlane.expressionInhibition > 0.58) {
|
|
452
|
+
parts.push(locale === "zh" ? "先不急着命名" : "do not rush to name it");
|
|
453
|
+
}
|
|
454
|
+
if (kernel.expressionMode === "brief") {
|
|
455
|
+
parts.push(locale === "zh" ? "表达收短" : "keep expression brief");
|
|
456
|
+
}
|
|
457
|
+
else if (kernel.socialDistance === "warm") {
|
|
458
|
+
parts.push(locale === "zh" ? "可稍微靠近" : "can lean slightly warm");
|
|
459
|
+
}
|
|
460
|
+
else if (kernel.socialDistance === "withdrawn") {
|
|
461
|
+
parts.push(locale === "zh" ? "保持距离" : "keep distance");
|
|
462
|
+
}
|
|
463
|
+
if (kernel.boundaryMode === "confirm-first") {
|
|
464
|
+
parts.push(locale === "zh" ? "先确认再行动" : "confirm before acting");
|
|
465
|
+
}
|
|
466
|
+
else if (kernel.boundaryMode === "guarded") {
|
|
467
|
+
parts.push(locale === "zh" ? "先守边界" : "guard boundaries first");
|
|
468
|
+
}
|
|
469
|
+
if (parts.length < 4 && kernel.dominantNeed) {
|
|
470
|
+
parts.push(NEED_LABELS[kernel.dominantNeed][li]);
|
|
471
|
+
}
|
|
472
|
+
else if (parts.length < 4 && kernel.taskPlane.focus <= 0.72) {
|
|
473
|
+
parts.push(ATTENTION_LABELS[kernel.attentionAnchor][li]);
|
|
474
|
+
}
|
|
475
|
+
const title = locale === "zh" ? "主观内核" : "Subjectivity Kernel";
|
|
476
|
+
return `[${title}] ${parts.join(locale === "zh" ? "," : ", ")}${locale === "zh" ? "。" : "."}`;
|
|
477
|
+
}
|