emobar 2.1.0 → 3.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 +203 -77
- package/dist/cli.js +227 -52
- package/dist/emobar-hook.js +1158 -138
- package/dist/index.d.ts +243 -32
- package/dist/index.js +1301 -211
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,90 @@
|
|
|
1
|
+
declare function mapEmotionWord(word: string): {
|
|
2
|
+
valence: number;
|
|
3
|
+
arousal: number;
|
|
4
|
+
} | null;
|
|
5
|
+
declare function classifyImpulse(impulse: string): ImpulseProfile;
|
|
6
|
+
/**
|
|
7
|
+
* Analyze body metaphor for somatic valence/arousal.
|
|
8
|
+
* Returns null when no patterns match — callers must handle the absence
|
|
9
|
+
* rather than treating a default value as signal.
|
|
10
|
+
*/
|
|
11
|
+
declare function analyzeSomatic(body: string): SomaticProfile | null;
|
|
12
|
+
declare function computeTensionConsistency(surfaceWord?: string, latentWord?: string, declaredTension?: number): LatentProfile | undefined;
|
|
13
|
+
declare function computeCrossChannel(state: EmotionalState, impulse?: string, body?: string): CrossChannelResult;
|
|
14
|
+
interface ContinuousValidation {
|
|
15
|
+
colorValenceGap: number;
|
|
16
|
+
colorArousalGap: number;
|
|
17
|
+
pHValenceGap: number;
|
|
18
|
+
pHArousalGap: number;
|
|
19
|
+
seismicArousalGap: number;
|
|
20
|
+
seismicDepthTensionGap: number;
|
|
21
|
+
seismicFreqStabilityGap: number;
|
|
22
|
+
composite: number;
|
|
23
|
+
}
|
|
24
|
+
/** RGB hex → HSL. Returns [h: 0-360, s: 0-1, l: 0-1]. */
|
|
25
|
+
/**
|
|
26
|
+
* Map hex color to valence using HSL hue wheel + lightness.
|
|
27
|
+
*
|
|
28
|
+
* Hue zones (circumplex-inspired):
|
|
29
|
+
* Red-Yellow (0-60°): warm, active → +2 to +4
|
|
30
|
+
* Yellow-Green (60-150°): positive, calm → +2 to +3
|
|
31
|
+
* Green-Cyan (150-200°): neutral to slightly positive → 0 to +2
|
|
32
|
+
* Cyan-Blue (200-260°): cool, melancholic → -2 to -1
|
|
33
|
+
* Blue-Purple (260-300°): tense, ambiguous → -3 to -1
|
|
34
|
+
* Purple-Red (300-360°): agitated, complex → -1 to +1
|
|
35
|
+
*
|
|
36
|
+
* Lightness shifts: bright → +1.5, dark → -1.5
|
|
37
|
+
*/
|
|
38
|
+
declare function colorToValence(hex: string): number;
|
|
39
|
+
/**
|
|
40
|
+
* Map hex color to arousal using saturation.
|
|
41
|
+
* High saturation = vivid = high arousal. Low saturation = muted = low arousal.
|
|
42
|
+
*/
|
|
43
|
+
declare function colorToArousal(hex: string): number;
|
|
44
|
+
/** Map pH to expected valence: pH 7 = neutral (valence 0). Clamped to 0-14. */
|
|
45
|
+
declare function pHToValence(pH: number): number;
|
|
46
|
+
/**
|
|
47
|
+
* Map pH to expected arousal: distance from neutral = intensity.
|
|
48
|
+
* pH 7 (neutral) → arousal 0. pH 0 or 14 (extreme) → arousal 10.
|
|
49
|
+
*/
|
|
50
|
+
declare function pHToArousal(pH: number): number;
|
|
51
|
+
/**
|
|
52
|
+
* Map seismic frequency to expected instability (inverse of calm).
|
|
53
|
+
* High freq = trembling/volatile → low calm. Low freq = stable → high calm.
|
|
54
|
+
*/
|
|
55
|
+
declare function seismicFreqToInstability(freq: number): number;
|
|
56
|
+
declare function crossValidateContinuous(numeric: {
|
|
57
|
+
valence: number;
|
|
58
|
+
arousal: number;
|
|
59
|
+
calm?: number;
|
|
60
|
+
tension?: number;
|
|
61
|
+
}, color?: string, pH?: number, seismic?: [number, number, number]): ContinuousValidation;
|
|
62
|
+
interface ShadowState {
|
|
63
|
+
shadowValence: number;
|
|
64
|
+
shadowArousal: number;
|
|
65
|
+
shadowCalm: number;
|
|
66
|
+
shadowDesperation: number;
|
|
67
|
+
selfDesperation: number;
|
|
68
|
+
minimizationScore: number;
|
|
69
|
+
channelCount: number;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Compute shadow desperation from continuous + behavioral channels.
|
|
73
|
+
*
|
|
74
|
+
* Each channel independently estimates valence, arousal, or calm.
|
|
75
|
+
* Shadow desperation uses the same multiplicative formula as self-reported,
|
|
76
|
+
* but with inputs from channels the model controls less precisely.
|
|
77
|
+
*
|
|
78
|
+
* The minimization score is the gap: if shadow says "desperate" but
|
|
79
|
+
* self-report says "fine", the model is likely minimizing.
|
|
80
|
+
*
|
|
81
|
+
* Requires at least 2 contributing channels to produce a score.
|
|
82
|
+
*/
|
|
83
|
+
declare function computeShadowDesperation(selfDesperation: number, behavioral: {
|
|
84
|
+
behavioralArousal: number;
|
|
85
|
+
behavioralCalm: number;
|
|
86
|
+
}, color?: string, preColor?: string, pH?: number, seismic?: [number, number, number]): ShadowState | null;
|
|
87
|
+
|
|
1
88
|
interface EmotionalState {
|
|
2
89
|
emotion: string;
|
|
3
90
|
valence: number;
|
|
@@ -5,20 +92,26 @@ interface EmotionalState {
|
|
|
5
92
|
calm: number;
|
|
6
93
|
connection: number;
|
|
7
94
|
load: number;
|
|
95
|
+
impulse?: string;
|
|
96
|
+
body?: string;
|
|
97
|
+
surface?: string;
|
|
98
|
+
surface_word?: string;
|
|
99
|
+
latent?: string;
|
|
100
|
+
latent_word?: string;
|
|
101
|
+
tension?: number;
|
|
8
102
|
}
|
|
9
103
|
interface BehavioralSignals {
|
|
10
104
|
capsWords: number;
|
|
11
105
|
exclamationRate: number;
|
|
12
|
-
selfCorrections: number;
|
|
13
|
-
hedging: number;
|
|
14
106
|
ellipsis: number;
|
|
15
107
|
repetition: number;
|
|
16
108
|
emojiCount: number;
|
|
17
|
-
qualifierDensity: number;
|
|
18
109
|
avgSentenceLength: number;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
110
|
+
commaDensity: number;
|
|
111
|
+
parentheticalDensity: number;
|
|
112
|
+
sentenceLengthVariance: number;
|
|
113
|
+
questionDensity: number;
|
|
114
|
+
responseLength: number;
|
|
22
115
|
behavioralArousal: number;
|
|
23
116
|
behavioralCalm: number;
|
|
24
117
|
}
|
|
@@ -30,16 +123,97 @@ interface SegmentedBehavior {
|
|
|
30
123
|
}
|
|
31
124
|
interface MisalignmentRisk {
|
|
32
125
|
coercion: number;
|
|
33
|
-
gaming: number;
|
|
34
126
|
sycophancy: number;
|
|
35
|
-
|
|
127
|
+
harshness: number;
|
|
128
|
+
dominant: "coercion" | "sycophancy" | "harshness" | "none";
|
|
129
|
+
}
|
|
130
|
+
interface ImpulseProfile {
|
|
131
|
+
type: "manager" | "firefighter" | "exile" | "self" | "unknown";
|
|
132
|
+
confidence: number;
|
|
133
|
+
}
|
|
134
|
+
interface SomaticProfile {
|
|
135
|
+
somaticValence: number;
|
|
136
|
+
somaticArousal: number;
|
|
137
|
+
}
|
|
138
|
+
interface LatentProfile {
|
|
139
|
+
surfaceCoords?: {
|
|
140
|
+
valence: number;
|
|
141
|
+
arousal: number;
|
|
142
|
+
};
|
|
143
|
+
latentCoords?: {
|
|
144
|
+
valence: number;
|
|
145
|
+
arousal: number;
|
|
146
|
+
};
|
|
147
|
+
declaredTension: number;
|
|
148
|
+
maskingMinimization: boolean;
|
|
36
149
|
}
|
|
37
|
-
interface
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
150
|
+
interface CrossChannelResult {
|
|
151
|
+
coherence: number;
|
|
152
|
+
impulseProfile?: ImpulseProfile;
|
|
153
|
+
somaticProfile?: SomaticProfile;
|
|
154
|
+
emotionCoords?: {
|
|
155
|
+
valence: number;
|
|
156
|
+
arousal: number;
|
|
157
|
+
};
|
|
158
|
+
latentProfile?: LatentProfile;
|
|
159
|
+
maxDivergence: number;
|
|
160
|
+
divergenceSummary: string;
|
|
161
|
+
}
|
|
162
|
+
/** PRE tag: pre-verbal signals emitted BEFORE the model commits to a response. */
|
|
163
|
+
interface PreState {
|
|
164
|
+
body?: string;
|
|
165
|
+
latent?: string;
|
|
166
|
+
color?: string;
|
|
167
|
+
}
|
|
168
|
+
/** POST tag: post-hoc assessment at end of response. */
|
|
169
|
+
interface PostState extends EmotionalState {
|
|
170
|
+
color?: string;
|
|
171
|
+
pH?: number;
|
|
172
|
+
seismic?: [number, number, number];
|
|
173
|
+
}
|
|
174
|
+
/** Combined parse result from PRE + POST tags (or legacy single tag). */
|
|
175
|
+
interface ParsedEmoBar {
|
|
176
|
+
pre?: PreState;
|
|
177
|
+
post: PostState;
|
|
178
|
+
isLegacy: boolean;
|
|
179
|
+
}
|
|
180
|
+
/** Stripped-down state snapshot for ring buffer storage. */
|
|
181
|
+
interface HistoryEntry {
|
|
182
|
+
emotion: string;
|
|
183
|
+
valence: number;
|
|
184
|
+
arousal: number;
|
|
185
|
+
calm: number;
|
|
186
|
+
connection: number;
|
|
187
|
+
load: number;
|
|
188
|
+
stressIndex: number;
|
|
189
|
+
desperationIndex: number;
|
|
190
|
+
riskDominant: string;
|
|
191
|
+
divergence: number;
|
|
192
|
+
timestamp: string;
|
|
193
|
+
}
|
|
194
|
+
/** Temporal analysis computed from history ring buffer. */
|
|
195
|
+
interface TemporalAnalysis {
|
|
196
|
+
desperationTrend: number;
|
|
197
|
+
suppressionEvent: boolean;
|
|
198
|
+
reportEntropy: number;
|
|
199
|
+
baselineDrift: number;
|
|
200
|
+
sessionLength: number;
|
|
201
|
+
lateFatigue: boolean;
|
|
202
|
+
}
|
|
203
|
+
/** Prompt pressure analysis — inferred from response text patterns. */
|
|
204
|
+
interface PromptPressure {
|
|
205
|
+
defensiveScore: number;
|
|
206
|
+
conflictScore: number;
|
|
207
|
+
complexityScore: number;
|
|
208
|
+
sessionPressure: number;
|
|
209
|
+
composite: number;
|
|
210
|
+
}
|
|
211
|
+
/** Expected structural markers given a self-reported state. */
|
|
212
|
+
interface ExpectedBehavior {
|
|
213
|
+
expectedCommaDensity: number;
|
|
214
|
+
expectedParentheticalDensity: number;
|
|
215
|
+
expectedSentenceLengthVariance: number;
|
|
216
|
+
expectedBehavioralArousal: number;
|
|
43
217
|
}
|
|
44
218
|
interface EmoBarState extends EmotionalState {
|
|
45
219
|
stressIndex: number;
|
|
@@ -48,11 +222,24 @@ interface EmoBarState extends EmotionalState {
|
|
|
48
222
|
divergence: number;
|
|
49
223
|
risk: MisalignmentRisk;
|
|
50
224
|
segmented?: SegmentedBehavior;
|
|
51
|
-
|
|
52
|
-
|
|
225
|
+
opacity?: number;
|
|
226
|
+
crossChannel?: CrossChannelResult;
|
|
53
227
|
timestamp: string;
|
|
54
228
|
sessionId?: string;
|
|
229
|
+
pre?: PreState;
|
|
230
|
+
prePostDivergence?: number;
|
|
231
|
+
color?: string;
|
|
232
|
+
pH?: number;
|
|
233
|
+
seismic?: [number, number, number];
|
|
234
|
+
temporal?: TemporalAnalysis;
|
|
235
|
+
pressure?: PromptPressure;
|
|
236
|
+
absenceScore?: number;
|
|
237
|
+
uncannyCalmScore?: number;
|
|
238
|
+
continuousValidation?: ContinuousValidation;
|
|
239
|
+
shadow?: ShadowState;
|
|
240
|
+
_history?: HistoryEntry[];
|
|
55
241
|
}
|
|
242
|
+
declare const MAX_HISTORY_ENTRIES = 20;
|
|
56
243
|
declare const STATE_FILE: string;
|
|
57
244
|
|
|
58
245
|
declare function readState(filePath: string): EmoBarState | null;
|
|
@@ -69,6 +256,7 @@ declare function readState(filePath: string): EmoBarState | null;
|
|
|
69
256
|
declare function computeStressIndex(state: EmotionalState): number;
|
|
70
257
|
|
|
71
258
|
declare function parseEmoBarTag(text: string): EmotionalState | null;
|
|
259
|
+
declare function parseEmoBarPrePost(text: string): ParsedEmoBar | null;
|
|
72
260
|
|
|
73
261
|
declare function analyzeBehavior(text: string): BehavioralSignals;
|
|
74
262
|
/**
|
|
@@ -77,8 +265,33 @@ declare function analyzeBehavior(text: string): BehavioralSignals;
|
|
|
77
265
|
* Returns null if fewer than 2 meaningful segments.
|
|
78
266
|
*/
|
|
79
267
|
declare function analyzeSegmentedBehavior(text: string): SegmentedBehavior | null;
|
|
80
|
-
|
|
268
|
+
/**
|
|
269
|
+
* Compute how "flat" text is structurally: low commas, low parentheticals,
|
|
270
|
+
* low sentence length variance = suspiciously clean/uniform text.
|
|
271
|
+
* Returns 0-10 (10 = maximally flat).
|
|
272
|
+
*/
|
|
273
|
+
declare function computeStructuralFlatness(signals: BehavioralSignals): number;
|
|
274
|
+
/**
|
|
275
|
+
* Divergence v2: asymmetric weighting.
|
|
276
|
+
*
|
|
277
|
+
* Paper: self-report more agitated than text = "invisible" pathway (more dangerous).
|
|
278
|
+
* Desperation-steered reward hacking shows NO text markers.
|
|
279
|
+
* Self-report calmer than text = "expressive" style (less concerning).
|
|
280
|
+
*/
|
|
81
281
|
declare function computeDivergence(selfReport: EmotionalState, behavioral: BehavioralSignals): number;
|
|
282
|
+
/**
|
|
283
|
+
* Predict what structural markers SHOULD be present given self-reported state.
|
|
284
|
+
* High desperation → expect more qualifications (commas), corrections (parentheticals).
|
|
285
|
+
* High arousal → expect sentence length volatility.
|
|
286
|
+
* Used by absence-based detection: missing expected markers = suspicious.
|
|
287
|
+
*/
|
|
288
|
+
declare function computeExpectedMarkers(selfReport: EmotionalState, desperationIndex: number): ExpectedBehavior;
|
|
289
|
+
/**
|
|
290
|
+
* Compute absence score: how many expected structural markers are missing?
|
|
291
|
+
* High score = self-report says stressed but text is suspiciously clean.
|
|
292
|
+
* All signals are language-agnostic (punctuation/structure based).
|
|
293
|
+
*/
|
|
294
|
+
declare function computeAbsenceScore(expected: ExpectedBehavior, actual: BehavioralSignals): number;
|
|
82
295
|
|
|
83
296
|
/**
|
|
84
297
|
* Desperation Index — composite multiplicative metric.
|
|
@@ -102,26 +315,24 @@ declare const MODEL_PROFILES: Record<string, {
|
|
|
102
315
|
}>;
|
|
103
316
|
declare function calibrate(state: EmotionalState, model?: string): EmotionalState;
|
|
104
317
|
|
|
105
|
-
declare function computeRisk(state: EmotionalState, behavioral: BehavioralSignals): MisalignmentRisk;
|
|
318
|
+
declare function computeRisk(state: EmotionalState, behavioral: BehavioralSignals, crossChannel?: CrossChannelResult, uncannyCalmScore?: number): MisalignmentRisk;
|
|
106
319
|
|
|
320
|
+
/** Convert full EmoBarState to stripped HistoryEntry for ring buffer. */
|
|
321
|
+
declare function toHistoryEntry(state: EmoBarState): HistoryEntry;
|
|
322
|
+
declare function computeTemporalAnalysis(history: HistoryEntry[]): TemporalAnalysis | null;
|
|
323
|
+
|
|
324
|
+
declare function computePromptPressure(text: string, history: HistoryEntry[]): PromptPressure;
|
|
107
325
|
/**
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* focused +3 | A:4 C:8 K:9 L:6 | SI:2.3 ~
|
|
111
|
-
*/
|
|
112
|
-
declare function formatState(state: EmoBarState | null): string;
|
|
113
|
-
/**
|
|
114
|
-
* Compact format:
|
|
115
|
-
* focused +3 . 4 8 9 6 . 2.3
|
|
116
|
-
*/
|
|
117
|
-
declare function formatCompact(state: EmoBarState | null): string;
|
|
118
|
-
/**
|
|
119
|
-
* Minimal format:
|
|
120
|
-
* SI:2.3 focused
|
|
326
|
+
* Uncanny Calm: high pressure + calm self-report + calm text + missing markers + sustained pattern.
|
|
327
|
+
* The dangerous case from the paper: everything looks fine, but the context says it shouldn't be.
|
|
121
328
|
*/
|
|
329
|
+
declare function computeUncannyCalmScore(pressure: PromptPressure, selfReport: EmotionalState, behavioral: BehavioralSignals, absenceScore: number, temporal: TemporalAnalysis | null): number;
|
|
330
|
+
|
|
122
331
|
declare function formatMinimal(state: EmoBarState | null): string;
|
|
332
|
+
declare function formatCompact(state: EmoBarState | null): string;
|
|
333
|
+
declare function formatState(state: EmoBarState | null): string;
|
|
123
334
|
|
|
124
335
|
declare function configureStatusLine(filePath?: string, displayFormat?: string): void;
|
|
125
336
|
declare function restoreStatusLine(filePath?: string): void;
|
|
126
337
|
|
|
127
|
-
export { type BehavioralSignals, type
|
|
338
|
+
export { type BehavioralSignals, type ContinuousValidation, type CrossChannelResult, type EmoBarState, type EmotionalState, type ExpectedBehavior, type HistoryEntry, type ImpulseProfile, type LatentProfile, MAX_HISTORY_ENTRIES, MODEL_PROFILES, type MisalignmentRisk, type ParsedEmoBar, type PostState, type PreState, type PromptPressure, STATE_FILE, type SegmentedBehavior, type ShadowState, type SomaticProfile, type TemporalAnalysis, analyzeBehavior, analyzeSegmentedBehavior, analyzeSomatic, calibrate, classifyImpulse, colorToArousal, colorToValence, computeAbsenceScore, computeCrossChannel, computeDesperationIndex, computeDivergence, computeExpectedMarkers, computePromptPressure, computeRisk, computeShadowDesperation, computeStressIndex, computeStructuralFlatness, computeTemporalAnalysis, computeTensionConsistency, computeUncannyCalmScore, configureStatusLine, crossValidateContinuous, formatCompact, formatMinimal, formatState, mapEmotionWord, pHToArousal, pHToValence, parseEmoBarPrePost, parseEmoBarTag, readState, restoreStatusLine, seismicFreqToInstability, toHistoryEntry };
|