psyche-ai 9.2.6 → 9.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/http.js +24 -2
- package/dist/adapters/langchain.d.ts +4 -0
- package/dist/adapters/langchain.js +23 -1
- package/dist/adapters/mcp.js +4 -2
- package/dist/core.d.ts +15 -4
- package/dist/core.js +87 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/prompt.js +2 -2
- package/dist/psyche-file.d.ts +5 -1
- package/dist/psyche-file.js +39 -1
- package/dist/relation-dynamics.d.ts +22 -1
- package/dist/relation-dynamics.js +431 -10
- package/dist/reply-envelope.d.ts +1 -0
- package/dist/reply-envelope.js +1 -0
- package/dist/response-contract.d.ts +1 -0
- package/dist/response-contract.js +47 -16
- package/dist/types.d.ts +64 -0
- package/dist/types.js +3 -0
- package/package.json +1 -1
package/dist/adapters/http.js
CHANGED
|
@@ -8,13 +8,31 @@
|
|
|
8
8
|
//
|
|
9
9
|
// Endpoints:
|
|
10
10
|
// POST /process-input { text, userId? } → { systemContext, dynamicContext, stimulus, policyModifiers?, subjectivityKernel?, responseContract?, generationControls?, policyContext }
|
|
11
|
-
// POST /process-output { text, userId? } → { cleanedText, stateChanged }
|
|
11
|
+
// POST /process-output { text, userId?, signals?, signalConfidence? } → { cleanedText, stateChanged }
|
|
12
12
|
// GET /state → PsycheState
|
|
13
13
|
// GET /protocol?locale=zh → { protocol }
|
|
14
14
|
//
|
|
15
15
|
// Zero dependencies — uses node:http only.
|
|
16
16
|
// ============================================================
|
|
17
17
|
import { createServer } from "node:http";
|
|
18
|
+
const VALID_WRITEBACK_SIGNALS = new Set([
|
|
19
|
+
"trust_up",
|
|
20
|
+
"trust_down",
|
|
21
|
+
"boundary_set",
|
|
22
|
+
"boundary_soften",
|
|
23
|
+
"repair_attempt",
|
|
24
|
+
"repair_landed",
|
|
25
|
+
"closeness_invite",
|
|
26
|
+
"withdrawal_mark",
|
|
27
|
+
"self_assertion",
|
|
28
|
+
"task_recenter",
|
|
29
|
+
]);
|
|
30
|
+
function parseSignals(value) {
|
|
31
|
+
if (!Array.isArray(value))
|
|
32
|
+
return undefined;
|
|
33
|
+
const parsed = value.filter((item) => (typeof item === "string" && VALID_WRITEBACK_SIGNALS.has(item)));
|
|
34
|
+
return parsed.length > 0 ? [...new Set(parsed)] : undefined;
|
|
35
|
+
}
|
|
18
36
|
// ── Server ───────────────────────────────────────────────────
|
|
19
37
|
/**
|
|
20
38
|
* Create an HTTP server that exposes PsycheEngine via REST API.
|
|
@@ -69,7 +87,11 @@ export function createPsycheServer(engine, opts) {
|
|
|
69
87
|
// POST /process-output
|
|
70
88
|
if (req.method === "POST" && url.pathname === "/process-output") {
|
|
71
89
|
const body = await readBody(req);
|
|
72
|
-
const result = await engine.processOutput(body.text ?? "", {
|
|
90
|
+
const result = await engine.processOutput(body.text ?? "", {
|
|
91
|
+
userId: body.userId,
|
|
92
|
+
signals: parseSignals(body.signals),
|
|
93
|
+
signalConfidence: typeof body.signalConfidence === "number" ? body.signalConfidence : undefined,
|
|
94
|
+
});
|
|
73
95
|
json(res, 200, result);
|
|
74
96
|
return;
|
|
75
97
|
}
|
|
@@ -28,6 +28,8 @@ import type { PsycheEngine } from "../core.js";
|
|
|
28
28
|
export declare class PsycheLangChain {
|
|
29
29
|
private readonly engine;
|
|
30
30
|
constructor(engine: PsycheEngine);
|
|
31
|
+
private readonly validSignals;
|
|
32
|
+
private parseSignals;
|
|
31
33
|
/**
|
|
32
34
|
* Get the system message to inject into the LLM call.
|
|
33
35
|
* Combines the protocol (cacheable) and dynamic context (per-turn).
|
|
@@ -59,5 +61,7 @@ export declare class PsycheLangChain {
|
|
|
59
61
|
*/
|
|
60
62
|
processResponse(text: string, opts?: {
|
|
61
63
|
userId?: string;
|
|
64
|
+
signals?: string[];
|
|
65
|
+
signalConfidence?: number;
|
|
62
66
|
}): Promise<string>;
|
|
63
67
|
}
|
|
@@ -43,6 +43,24 @@ export class PsycheLangChain {
|
|
|
43
43
|
constructor(engine) {
|
|
44
44
|
this.engine = engine;
|
|
45
45
|
}
|
|
46
|
+
validSignals = new Set([
|
|
47
|
+
"trust_up",
|
|
48
|
+
"trust_down",
|
|
49
|
+
"boundary_set",
|
|
50
|
+
"boundary_soften",
|
|
51
|
+
"repair_attempt",
|
|
52
|
+
"repair_landed",
|
|
53
|
+
"closeness_invite",
|
|
54
|
+
"withdrawal_mark",
|
|
55
|
+
"self_assertion",
|
|
56
|
+
"task_recenter",
|
|
57
|
+
]);
|
|
58
|
+
parseSignals(signals) {
|
|
59
|
+
if (!signals)
|
|
60
|
+
return undefined;
|
|
61
|
+
const parsed = signals.filter((signal) => this.validSignals.has(signal));
|
|
62
|
+
return parsed.length > 0 ? [...new Set(parsed)] : undefined;
|
|
63
|
+
}
|
|
46
64
|
/**
|
|
47
65
|
* Get the system message to inject into the LLM call.
|
|
48
66
|
* Combines the protocol (cacheable) and dynamic context (per-turn).
|
|
@@ -80,7 +98,11 @@ export class PsycheLangChain {
|
|
|
80
98
|
* Call this AFTER the LLM invocation, before showing output to the user.
|
|
81
99
|
*/
|
|
82
100
|
async processResponse(text, opts) {
|
|
83
|
-
const result = await this.engine.processOutput(text,
|
|
101
|
+
const result = await this.engine.processOutput(text, {
|
|
102
|
+
userId: opts?.userId,
|
|
103
|
+
signals: this.parseSignals(opts?.signals),
|
|
104
|
+
signalConfidence: opts?.signalConfidence,
|
|
105
|
+
});
|
|
84
106
|
return result.cleanedText;
|
|
85
107
|
}
|
|
86
108
|
}
|
package/dist/adapters/mcp.js
CHANGED
|
@@ -174,9 +174,11 @@ server.tool("process_output", "Process the LLM's response through the emotional
|
|
|
174
174
|
"emotional contagion. Call this AFTER generating a response.", {
|
|
175
175
|
text: z.string().describe("The LLM's response text"),
|
|
176
176
|
userId: z.string().optional().describe("Optional user ID"),
|
|
177
|
-
|
|
177
|
+
signals: z.array(z.string()).optional().describe("Optional sparse writeback signals from the host"),
|
|
178
|
+
signalConfidence: z.number().min(0).max(1).optional().describe("Optional confidence for the supplied signals"),
|
|
179
|
+
}, async ({ text, userId, signals, signalConfidence }) => {
|
|
178
180
|
const eng = await getEngine();
|
|
179
|
-
const result = await eng.processOutput(text, { userId });
|
|
181
|
+
const result = await eng.processOutput(text, { userId, signals: signals, signalConfidence });
|
|
180
182
|
return {
|
|
181
183
|
content: [{
|
|
182
184
|
type: "text",
|
package/dist/core.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PsycheState, StimulusType, Locale, MBTIType, OutcomeScore, PsycheMode, PersonalityTraits, PolicyModifiers, ClassifierProvider, SubjectivityKernel, ResponseContract, GenerationControls } from "./types.js";
|
|
1
|
+
import type { PsycheState, StimulusType, Locale, MBTIType, OutcomeScore, PsycheMode, PersonalityTraits, PolicyModifiers, ClassifierProvider, SubjectivityKernel, ResponseContract, GenerationControls, SessionBridgeState, WritebackCalibrationFeedback, WritebackSignalType } from "./types.js";
|
|
2
2
|
import type { StorageAdapter } from "./storage.js";
|
|
3
3
|
import type { DiagnosticReport, SessionMetrics } from "./diagnostics.js";
|
|
4
4
|
export interface PsycheEngineConfig {
|
|
@@ -36,6 +36,8 @@ export interface ProcessInputResult {
|
|
|
36
36
|
dynamicContext: string;
|
|
37
37
|
/** Detected stimulus type from user input, null if none */
|
|
38
38
|
stimulus: StimulusType | null;
|
|
39
|
+
/** Confidence of the primary algorithmic stimulus guess, if any */
|
|
40
|
+
stimulusConfidence?: number;
|
|
39
41
|
/** v9: Structured behavioral policy modifiers — machine-readable "off baseline" signals */
|
|
40
42
|
policyModifiers?: PolicyModifiers;
|
|
41
43
|
/** v9.3: Compact machine-readable subjective state for AI-first hosts */
|
|
@@ -44,6 +46,10 @@ export interface ProcessInputResult {
|
|
|
44
46
|
responseContract?: ResponseContract;
|
|
45
47
|
/** v9.3: Mechanical host controls derived from the reply envelope */
|
|
46
48
|
generationControls?: GenerationControls;
|
|
49
|
+
/** v9.2.7: cold-start carry derived from persisted relation state */
|
|
50
|
+
sessionBridge?: SessionBridgeState | null;
|
|
51
|
+
/** v9.2.8: sparse writeback signals evaluated on the latest turn */
|
|
52
|
+
writebackFeedback?: WritebackCalibrationFeedback[];
|
|
47
53
|
/**
|
|
48
54
|
* v9: Ready-to-use LLM prompt fragment summarizing current behavioral policy.
|
|
49
55
|
*
|
|
@@ -65,6 +71,11 @@ export interface ProcessOutputResult {
|
|
|
65
71
|
/** Whether chemistry was meaningfully updated (contagion or psyche_update) */
|
|
66
72
|
stateChanged: boolean;
|
|
67
73
|
}
|
|
74
|
+
export interface ProcessOutputOptions {
|
|
75
|
+
userId?: string;
|
|
76
|
+
signals?: WritebackSignalType[];
|
|
77
|
+
signalConfidence?: number;
|
|
78
|
+
}
|
|
68
79
|
export interface ProcessOutcomeResult {
|
|
69
80
|
/** Outcome evaluation score (-1 to 1) */
|
|
70
81
|
outcomeScore: OutcomeScore;
|
|
@@ -89,6 +100,8 @@ export declare class PsycheEngine {
|
|
|
89
100
|
private lastReport;
|
|
90
101
|
/** URL for auto-submitting diagnostic reports */
|
|
91
102
|
private readonly feedbackUrl;
|
|
103
|
+
/** Most recent algorithmic stimulus read + confidence band */
|
|
104
|
+
private lastStimulusAssessment;
|
|
92
105
|
constructor(config: PsycheEngineConfig | undefined, storage: StorageAdapter);
|
|
93
106
|
/**
|
|
94
107
|
* Load or create initial state. Must be called before processInput/processOutput.
|
|
@@ -105,9 +118,7 @@ export declare class PsycheEngine {
|
|
|
105
118
|
* Phase 2: Process LLM output text.
|
|
106
119
|
* Parses <psyche_update> tags, applies contagion, strips tags.
|
|
107
120
|
*/
|
|
108
|
-
processOutput(text: string, opts?:
|
|
109
|
-
userId?: string;
|
|
110
|
-
}): Promise<ProcessOutputResult>;
|
|
121
|
+
processOutput(text: string, opts?: ProcessOutputOptions): Promise<ProcessOutputResult>;
|
|
111
122
|
/**
|
|
112
123
|
* Phase 3 (optional): Explicitly evaluate the outcome of the last interaction.
|
|
113
124
|
*
|
package/dist/core.js
CHANGED
|
@@ -32,8 +32,18 @@ import { assessEthics, buildEthicalContext } from "./ethics.js";
|
|
|
32
32
|
import { computeCircadianModulation, computeHomeostaticPressure, computeEnergyDepletion, computeEnergyRecovery } from "./circadian.js";
|
|
33
33
|
import { computeAutonomicResult } from "./autonomic.js";
|
|
34
34
|
import { computePrimarySystems, computeSystemInteractions, gatePrimarySystemsByAutonomic, describeBehavioralTendencies, } from "./primary-systems.js";
|
|
35
|
-
import { applyRelationalTurn } from "./relation-dynamics.js";
|
|
35
|
+
import { applyRelationalTurn, applySessionBridge, applyWritebackSignals, createWritebackCalibrations, evaluateWritebackCalibrations } from "./relation-dynamics.js";
|
|
36
36
|
import { deriveReplyEnvelope } from "./reply-envelope.js";
|
|
37
|
+
function formatWritebackFeedbackNote(feedback, locale) {
|
|
38
|
+
const top = feedback?.[0];
|
|
39
|
+
if (!top)
|
|
40
|
+
return undefined;
|
|
41
|
+
if (locale === "zh") {
|
|
42
|
+
const effect = top.effect === "converging" ? "收敛" : top.effect === "diverging" ? "发散" : "持平";
|
|
43
|
+
return `写回:${top.signal} ${effect}。`;
|
|
44
|
+
}
|
|
45
|
+
return `Writeback: ${top.signal} ${top.effect}.`;
|
|
46
|
+
}
|
|
37
47
|
const NOOP_LOGGER = { info: () => { }, warn: () => { }, debug: () => { } };
|
|
38
48
|
const REPAIRING_STIMULI = new Set(["praise", "validation", "intimacy"]);
|
|
39
49
|
const RELATIONSHIP_DELTAS = {
|
|
@@ -127,6 +137,8 @@ export class PsycheEngine {
|
|
|
127
137
|
lastReport = null;
|
|
128
138
|
/** URL for auto-submitting diagnostic reports */
|
|
129
139
|
feedbackUrl;
|
|
140
|
+
/** Most recent algorithmic stimulus read + confidence band */
|
|
141
|
+
lastStimulusAssessment = null;
|
|
130
142
|
constructor(config = {}, storage) {
|
|
131
143
|
this.traits = config.traits;
|
|
132
144
|
this.classifier = config.classifier ?? new BuiltInClassifier();
|
|
@@ -204,6 +216,12 @@ export class PsycheEngine {
|
|
|
204
216
|
if (!loaded.pendingRelationSignals) {
|
|
205
217
|
loaded.pendingRelationSignals = { _default: [] };
|
|
206
218
|
}
|
|
219
|
+
if (!loaded.pendingWritebackCalibrations) {
|
|
220
|
+
loaded.pendingWritebackCalibrations = [];
|
|
221
|
+
}
|
|
222
|
+
if (!loaded.lastWritebackFeedback) {
|
|
223
|
+
loaded.lastWritebackFeedback = [];
|
|
224
|
+
}
|
|
207
225
|
this.state = loaded;
|
|
208
226
|
}
|
|
209
227
|
else {
|
|
@@ -219,6 +237,8 @@ export class PsycheEngine {
|
|
|
219
237
|
*/
|
|
220
238
|
async processInput(text, opts) {
|
|
221
239
|
let state = this.ensureInitialized();
|
|
240
|
+
let sessionBridge = null;
|
|
241
|
+
let writebackFeedback = [];
|
|
222
242
|
// ── Auto-learning: evaluate previous turn's outcome ──────
|
|
223
243
|
if (this.pendingPrediction && text.length > 0) {
|
|
224
244
|
const nextClassifications = classifyStimulus(text);
|
|
@@ -261,6 +281,9 @@ export class PsycheEngine {
|
|
|
261
281
|
}
|
|
262
282
|
// P12: Track session start for homeostatic pressure
|
|
263
283
|
if (!state.sessionStartedAt) {
|
|
284
|
+
const bridged = applySessionBridge(state, { userId: opts?.userId, now: now.toISOString() });
|
|
285
|
+
state = bridged.state;
|
|
286
|
+
sessionBridge = bridged.bridge;
|
|
264
287
|
state = { ...state, sessionStartedAt: now.toISOString() };
|
|
265
288
|
}
|
|
266
289
|
// Apply homeostatic pressure (fatigue from extended sessions)
|
|
@@ -311,6 +334,7 @@ export class PsycheEngine {
|
|
|
311
334
|
}
|
|
312
335
|
}
|
|
313
336
|
const primary = classifications[0];
|
|
337
|
+
const primaryConfidence = primary?.confidence ?? 0;
|
|
314
338
|
let current = state.current;
|
|
315
339
|
if (primary && primary.confidence >= 0.5) {
|
|
316
340
|
appliedStimulus = primary.type;
|
|
@@ -334,6 +358,18 @@ export class PsycheEngine {
|
|
|
334
358
|
if (appliedStimulus) {
|
|
335
359
|
state = applyRelationshipDrift(state, appliedStimulus, opts?.userId);
|
|
336
360
|
}
|
|
361
|
+
this.lastStimulusAssessment = {
|
|
362
|
+
stimulus: primary?.type ?? null,
|
|
363
|
+
confidence: primaryConfidence,
|
|
364
|
+
overrideWindow: primaryConfidence >= 0.78 ? "narrow" : primaryConfidence >= 0.62 ? "balanced" : "wide",
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
this.lastStimulusAssessment = {
|
|
369
|
+
stimulus: null,
|
|
370
|
+
confidence: 0,
|
|
371
|
+
overrideWindow: "wide",
|
|
372
|
+
};
|
|
337
373
|
}
|
|
338
374
|
// v9: Deplete energy budgets from this interaction turn
|
|
339
375
|
energyBudgets = computeEnergyDepletion(energyBudgets, appliedStimulus, isExtravert);
|
|
@@ -361,6 +397,9 @@ export class PsycheEngine {
|
|
|
361
397
|
},
|
|
362
398
|
};
|
|
363
399
|
}
|
|
400
|
+
const writebackEvaluation = evaluateWritebackCalibrations(state);
|
|
401
|
+
state = writebackEvaluation.state;
|
|
402
|
+
writebackFeedback = writebackEvaluation.feedback;
|
|
364
403
|
// ── Locale (used by multiple subsystems below) ──────────
|
|
365
404
|
const locale = state.meta.locale ?? this.cfg.locale;
|
|
366
405
|
// ── P7+P10: Autonomic nervous system + Processing depth ────
|
|
@@ -517,7 +556,10 @@ export class PsycheEngine {
|
|
|
517
556
|
this.diagnosticCollector.recordInput(appliedStimulus, appliedStimulus ? 1.0 : 0.0, state.current, appraisalAxes);
|
|
518
557
|
}
|
|
519
558
|
// Build metacognitive and decision context strings
|
|
520
|
-
const
|
|
559
|
+
const writebackNote = formatWritebackFeedbackNote(writebackFeedback, locale);
|
|
560
|
+
const metacogNote = writebackNote
|
|
561
|
+
? [writebackNote, metacognitiveAssessment?.metacognitiveNote].filter(Boolean).join("\n")
|
|
562
|
+
: metacognitiveAssessment?.metacognitiveNote;
|
|
521
563
|
const decisionCtx = buildDecisionContext(state);
|
|
522
564
|
const ethicsCtx = ethicalAssessment ? buildEthicalContext(ethicalAssessment, locale) : undefined;
|
|
523
565
|
const sharedCtx = sharedState ? buildSharedIntentionalityContext(sharedState, locale) : undefined;
|
|
@@ -527,6 +569,7 @@ export class PsycheEngine {
|
|
|
527
569
|
locale,
|
|
528
570
|
userText: text || undefined,
|
|
529
571
|
algorithmStimulus: appliedStimulus,
|
|
572
|
+
classificationConfidence: this.lastStimulusAssessment?.confidence,
|
|
530
573
|
personalityIntensity: this.cfg.personalityIntensity,
|
|
531
574
|
relationContext: relationalTurn.relationContext,
|
|
532
575
|
});
|
|
@@ -561,10 +604,13 @@ export class PsycheEngine {
|
|
|
561
604
|
policyContext: replyEnvelope.policyContext || undefined,
|
|
562
605
|
}),
|
|
563
606
|
stimulus: appliedStimulus,
|
|
607
|
+
stimulusConfidence: this.lastStimulusAssessment?.confidence,
|
|
564
608
|
policyModifiers: replyEnvelope.policyModifiers,
|
|
565
609
|
subjectivityKernel: replyEnvelope.subjectivityKernel,
|
|
566
610
|
responseContract: replyEnvelope.responseContract,
|
|
567
611
|
generationControls: replyEnvelope.generationControls,
|
|
612
|
+
sessionBridge,
|
|
613
|
+
writebackFeedback,
|
|
568
614
|
policyContext: replyEnvelope.policyContext,
|
|
569
615
|
};
|
|
570
616
|
}
|
|
@@ -582,10 +628,13 @@ export class PsycheEngine {
|
|
|
582
628
|
policyContext: replyEnvelope.policyContext || undefined,
|
|
583
629
|
}),
|
|
584
630
|
stimulus: appliedStimulus,
|
|
631
|
+
stimulusConfidence: this.lastStimulusAssessment?.confidence,
|
|
585
632
|
policyModifiers: replyEnvelope.policyModifiers,
|
|
586
633
|
subjectivityKernel: replyEnvelope.subjectivityKernel,
|
|
587
634
|
responseContract: replyEnvelope.responseContract,
|
|
588
635
|
generationControls: replyEnvelope.generationControls,
|
|
636
|
+
sessionBridge,
|
|
637
|
+
writebackFeedback,
|
|
589
638
|
policyContext: replyEnvelope.policyContext,
|
|
590
639
|
};
|
|
591
640
|
}
|
|
@@ -645,6 +694,8 @@ export class PsycheEngine {
|
|
|
645
694
|
// Anti-sycophancy: track agreement streak
|
|
646
695
|
state = updateAgreementStreak(state, text);
|
|
647
696
|
// Parse and merge <psyche_update> from LLM output
|
|
697
|
+
let combinedSignals = [];
|
|
698
|
+
let combinedSignalConfidence = opts?.signalConfidence;
|
|
648
699
|
if (text.includes("<psyche_update>")) {
|
|
649
700
|
const parseResult = parsePsycheUpdate(text, NOOP_LOGGER);
|
|
650
701
|
if (parseResult) {
|
|
@@ -652,7 +703,8 @@ export class PsycheEngine {
|
|
|
652
703
|
stateChanged = true;
|
|
653
704
|
// LLM-assisted classification: if algorithm didn't apply a stimulus
|
|
654
705
|
// but LLM classified one, retroactively apply chemistry + drives
|
|
655
|
-
|
|
706
|
+
const overrideAllowed = this.lastStimulusAssessment?.overrideWindow !== "narrow";
|
|
707
|
+
if (parseResult.llmStimulus && (!this._lastAlgorithmApplied || overrideAllowed)) {
|
|
656
708
|
state = {
|
|
657
709
|
...state,
|
|
658
710
|
drives: feedDrives(state.drives, parseResult.llmStimulus),
|
|
@@ -660,11 +712,38 @@ export class PsycheEngine {
|
|
|
660
712
|
const effectiveSensitivity = computeEffectiveSensitivity(getSensitivity(state.mbti), state.drives, parseResult.llmStimulus, state.traitDrift);
|
|
661
713
|
state = {
|
|
662
714
|
...state,
|
|
663
|
-
current: applyStimulus(state.current, parseResult.llmStimulus, effectiveSensitivity, this.cfg.maxChemicalDelta, NOOP_LOGGER),
|
|
715
|
+
current: applyStimulus(state.current, parseResult.llmStimulus, effectiveSensitivity * (overrideAllowed && this._lastAlgorithmApplied ? 0.8 : 1), this.cfg.maxChemicalDelta, NOOP_LOGGER),
|
|
664
716
|
};
|
|
665
717
|
}
|
|
718
|
+
if (parseResult.signals && parseResult.signals.length > 0) {
|
|
719
|
+
combinedSignals.push(...parseResult.signals);
|
|
720
|
+
combinedSignalConfidence = Math.max(combinedSignalConfidence ?? 0, parseResult.signalConfidence ?? 0);
|
|
721
|
+
}
|
|
666
722
|
}
|
|
667
723
|
}
|
|
724
|
+
if (opts?.signals && opts.signals.length > 0) {
|
|
725
|
+
combinedSignals.push(...opts.signals);
|
|
726
|
+
combinedSignalConfidence = Math.max(combinedSignalConfidence ?? 0, opts.signalConfidence ?? 0);
|
|
727
|
+
}
|
|
728
|
+
if (combinedSignals.length > 0) {
|
|
729
|
+
const dedupedSignals = [...new Set(combinedSignals)];
|
|
730
|
+
const pending = createWritebackCalibrations(state, dedupedSignals, {
|
|
731
|
+
userId: opts?.userId,
|
|
732
|
+
confidence: combinedSignalConfidence,
|
|
733
|
+
});
|
|
734
|
+
state = applyWritebackSignals(state, dedupedSignals, {
|
|
735
|
+
userId: opts?.userId,
|
|
736
|
+
confidence: combinedSignalConfidence,
|
|
737
|
+
});
|
|
738
|
+
state = {
|
|
739
|
+
...state,
|
|
740
|
+
pendingWritebackCalibrations: [
|
|
741
|
+
...(state.pendingWritebackCalibrations ?? []),
|
|
742
|
+
...pending,
|
|
743
|
+
].slice(-12),
|
|
744
|
+
};
|
|
745
|
+
stateChanged = true;
|
|
746
|
+
}
|
|
668
747
|
// Persist
|
|
669
748
|
this.state = state;
|
|
670
749
|
await this.storage.save(state);
|
|
@@ -850,6 +929,8 @@ export class PsycheEngine {
|
|
|
850
929
|
},
|
|
851
930
|
},
|
|
852
931
|
pendingRelationSignals: { _default: [] },
|
|
932
|
+
pendingWritebackCalibrations: [],
|
|
933
|
+
lastWritebackFeedback: [],
|
|
853
934
|
meta: {
|
|
854
935
|
agentName: name,
|
|
855
936
|
createdAt: now,
|
|
@@ -889,6 +970,8 @@ export class PsycheEngine {
|
|
|
889
970
|
},
|
|
890
971
|
},
|
|
891
972
|
pendingRelationSignals: { _default: [] },
|
|
973
|
+
pendingWritebackCalibrations: [],
|
|
974
|
+
lastWritebackFeedback: [],
|
|
892
975
|
relationships: opts?.preserveRelationships !== false
|
|
893
976
|
? state.relationships
|
|
894
977
|
: { _default: { ...DEFAULT_RELATIONSHIP } },
|
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, PersonalityTraits, PsycheMode, PolicyModifiers, SubjectivityKernel, ResponseContract, GenerationControls, AppraisalAxes, SubjectResidue, TaskPlaneState, SubjectPlaneState, RelationPlaneState, AmbiguityPlaneState, RelationMoveType, RelationMove, OpenLoopType, OpenLoopState, PendingRelationSignalState, DyadicFieldState, TraitDriftState, EnergyBudgets, ClassifierProvider, ClassifierContext, ClassificationResult, } 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, PolicyModifiers, SubjectivityKernel, ResponseContract, GenerationControls, AppraisalAxes, SubjectResidue, TaskPlaneState, SubjectPlaneState, RelationPlaneState, AmbiguityPlaneState, RelationMoveType, RelationMove, OpenLoopType, OpenLoopState, PendingRelationSignalState, DyadicFieldState, SessionBridgeState, WritebackSignalType, WritebackSignalWeightMap, PendingWritebackCalibration, WritebackCalibrationFeedback, WritebackCalibrationMetric, TraitDriftState, EnergyBudgets, ClassifierProvider, ClassifierContext, ClassificationResult, } 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, DEFAULT_TRAIT_DRIFT, DEFAULT_ENERGY_BUDGETS, DEFAULT_APPRAISAL_AXES, DEFAULT_SUBJECT_RESIDUE, DEFAULT_DYADIC_FIELD, } from "./types.js";
|
|
7
7
|
export { computeSelfReflection, computeEmotionalTendency, buildSelfReflectionContext } from "./self-recognition.js";
|
|
8
8
|
export type { SelfReflection } from "./self-recognition.js";
|
|
@@ -27,7 +27,7 @@ export { computeSubjectivityKernel, buildSubjectivityContext } from "./subjectiv
|
|
|
27
27
|
export { computeResponseContract, buildResponseContractContext } from "./response-contract.js";
|
|
28
28
|
export { deriveGenerationControls } from "./host-controls.js";
|
|
29
29
|
export { computeAppraisalAxes, mergeAppraisalResidue, getResidueIntensity } from "./appraisal.js";
|
|
30
|
-
export { computeRelationMove, evolveDyadicField, evolvePendingRelationSignals, getLoopPressure } from "./relation-dynamics.js";
|
|
30
|
+
export { computeRelationMove, evolveDyadicField, evolvePendingRelationSignals, getLoopPressure, applySessionBridge, applyWritebackSignals, createWritebackCalibrations, evaluateWritebackCalibrations, } from "./relation-dynamics.js";
|
|
31
31
|
export { computeExperientialField, computeCoherence, detectUnnamedEmotion, computeAffectCore } from "./experiential-field.js";
|
|
32
32
|
export type { ExperientialField, ExperientialQuality, ConstructionContext } from "./experiential-field.js";
|
|
33
33
|
export { computeGenerativeSelf, predictSelfReaction, detectInternalConflicts, buildIdentityNarrative } from "./generative-self.js";
|
package/dist/index.js
CHANGED
|
@@ -38,7 +38,7 @@ export { computeSubjectivityKernel, buildSubjectivityContext } from "./subjectiv
|
|
|
38
38
|
export { computeResponseContract, buildResponseContractContext } from "./response-contract.js";
|
|
39
39
|
export { deriveGenerationControls } from "./host-controls.js";
|
|
40
40
|
export { computeAppraisalAxes, mergeAppraisalResidue, getResidueIntensity } from "./appraisal.js";
|
|
41
|
-
export { computeRelationMove, evolveDyadicField, evolvePendingRelationSignals, getLoopPressure } from "./relation-dynamics.js";
|
|
41
|
+
export { computeRelationMove, evolveDyadicField, evolvePendingRelationSignals, getLoopPressure, applySessionBridge, applyWritebackSignals, createWritebackCalibrations, evaluateWritebackCalibrations, } from "./relation-dynamics.js";
|
|
42
42
|
// Experiential field (P6 + P8 Barrett construction)
|
|
43
43
|
export { computeExperientialField, computeCoherence, detectUnnamedEmotion, computeAffectCore } from "./experiential-field.js";
|
|
44
44
|
// Generative self (P6)
|
package/dist/prompt.js
CHANGED
|
@@ -468,8 +468,8 @@ function buildMirrorConstraints(userText, locale) {
|
|
|
468
468
|
function buildCompactSensingContext(_userText, locale, algorithmStimulus) {
|
|
469
469
|
if (locale === "zh") {
|
|
470
470
|
return algorithmStimulus
|
|
471
|
-
? `[情绪感知] 算法初判:${algorithmStimulus}
|
|
472
|
-
: `[情绪感知]
|
|
471
|
+
? `[情绪感知] 算法初判:${algorithmStimulus};你终判。`
|
|
472
|
+
: `[情绪感知] 情绪由你终判。`;
|
|
473
473
|
}
|
|
474
474
|
return algorithmStimulus
|
|
475
475
|
? `[Emotional Sensing] Algorithm hint: ${algorithmStimulus}; final tonal read is yours.`
|
package/dist/psyche-file.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PsycheState, MBTIType, ChemicalState, RelationshipState, Locale, StimulusType, ChemicalSnapshot } from "./types.js";
|
|
1
|
+
import type { PsycheState, MBTIType, ChemicalState, RelationshipState, Locale, StimulusType, ChemicalSnapshot, WritebackSignalType } from "./types.js";
|
|
2
2
|
export interface SemanticTurnSummary {
|
|
3
3
|
summary: string;
|
|
4
4
|
points?: string[];
|
|
@@ -93,6 +93,10 @@ export interface PsycheUpdateResult {
|
|
|
93
93
|
state: Partial<PsycheState>;
|
|
94
94
|
/** LLM-assisted stimulus classification (when algorithm was uncertain) */
|
|
95
95
|
llmStimulus?: StimulusType;
|
|
96
|
+
/** Sparse agent-authored writeback signals */
|
|
97
|
+
signals?: WritebackSignalType[];
|
|
98
|
+
/** Optional writeback confidence */
|
|
99
|
+
signalConfidence?: number;
|
|
96
100
|
}
|
|
97
101
|
/**
|
|
98
102
|
* Parse a <psyche_update> block from LLM output.
|
package/dist/psyche-file.js
CHANGED
|
@@ -710,10 +710,42 @@ export function parsePsycheUpdate(text, logger = NOOP_LOGGER) {
|
|
|
710
710
|
llmStimulus = candidate;
|
|
711
711
|
}
|
|
712
712
|
}
|
|
713
|
+
const VALID_WRITEBACK_SIGNALS = new Set([
|
|
714
|
+
"trust_up",
|
|
715
|
+
"trust_down",
|
|
716
|
+
"boundary_set",
|
|
717
|
+
"boundary_soften",
|
|
718
|
+
"repair_attempt",
|
|
719
|
+
"repair_landed",
|
|
720
|
+
"closeness_invite",
|
|
721
|
+
"withdrawal_mark",
|
|
722
|
+
"self_assertion",
|
|
723
|
+
"task_recenter",
|
|
724
|
+
]);
|
|
725
|
+
let signals;
|
|
726
|
+
const signalsMatch = block.match(/signals\s*[::]\s*([^\n]+)/i);
|
|
727
|
+
if (signalsMatch) {
|
|
728
|
+
const parsed = signalsMatch[1]
|
|
729
|
+
.split(/[,\s|]+/)
|
|
730
|
+
.map((item) => item.trim())
|
|
731
|
+
.filter(Boolean)
|
|
732
|
+
.filter((item) => VALID_WRITEBACK_SIGNALS.has(item));
|
|
733
|
+
if (parsed.length > 0) {
|
|
734
|
+
signals = [...new Set(parsed)];
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
let signalConfidence;
|
|
738
|
+
const signalConfidenceMatch = block.match(/(?:signalConfidence|signalsConfidence|signal_confidence)\s*[::]\s*([\d.]+)/i);
|
|
739
|
+
if (signalConfidenceMatch) {
|
|
740
|
+
const parsed = parseFloat(signalConfidenceMatch[1]);
|
|
741
|
+
if (isFinite(parsed)) {
|
|
742
|
+
signalConfidence = Math.max(0, Math.min(1, parsed));
|
|
743
|
+
}
|
|
744
|
+
}
|
|
713
745
|
// Parse relationship updates
|
|
714
746
|
const trustMatch = block.match(/(?:信任度|trust)\s*[::]\s*(\d+)/i);
|
|
715
747
|
const intimacyMatch = block.match(/(?:亲密度|intimacy)\s*[::]\s*(\d+)/i);
|
|
716
|
-
if (Object.keys(updates).length === 0 && !empathyLog && !trustMatch && !llmStimulus) {
|
|
748
|
+
if (Object.keys(updates).length === 0 && !empathyLog && !trustMatch && !llmStimulus && !signals) {
|
|
717
749
|
logger.debug(t("log.parse_debug", "zh", { snippet: block.slice(0, 100) }));
|
|
718
750
|
return null;
|
|
719
751
|
}
|
|
@@ -738,6 +770,12 @@ export function parsePsycheUpdate(text, logger = NOOP_LOGGER) {
|
|
|
738
770
|
if (llmStimulus) {
|
|
739
771
|
result.llmStimulus = llmStimulus;
|
|
740
772
|
}
|
|
773
|
+
if (signals) {
|
|
774
|
+
result.signals = signals;
|
|
775
|
+
}
|
|
776
|
+
if (signalConfidence !== undefined) {
|
|
777
|
+
result.signalConfidence = signalConfidence;
|
|
778
|
+
}
|
|
741
779
|
return result;
|
|
742
780
|
}
|
|
743
781
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PendingRelationSignalState, AppraisalAxes, DyadicFieldState, PsycheState, RelationshipState, ResolvedRelationContext, PsycheMode, RelationMove, StimulusType } from "./types.js";
|
|
1
|
+
import type { PendingRelationSignalState, AppraisalAxes, DyadicFieldState, PendingWritebackCalibration, PsycheState, RelationshipState, ResolvedRelationContext, PsycheMode, RelationMove, SessionBridgeState, StimulusType, WritebackCalibrationFeedback, WritebackSignalType } from "./types.js";
|
|
2
2
|
export declare function computeRelationMove(text: string, opts?: {
|
|
3
3
|
appraisal?: AppraisalAxes;
|
|
4
4
|
stimulus?: StimulusType | null;
|
|
@@ -7,6 +7,27 @@ export declare function computeRelationMove(text: string, opts?: {
|
|
|
7
7
|
relationship?: RelationshipState;
|
|
8
8
|
}): RelationMove;
|
|
9
9
|
export declare function resolveRelationContext(state: PsycheState, userId?: string): ResolvedRelationContext;
|
|
10
|
+
export declare function applySessionBridge(state: PsycheState, opts?: {
|
|
11
|
+
userId?: string;
|
|
12
|
+
now?: string;
|
|
13
|
+
}): {
|
|
14
|
+
state: PsycheState;
|
|
15
|
+
bridge: SessionBridgeState | null;
|
|
16
|
+
};
|
|
17
|
+
export declare function createWritebackCalibrations(state: PsycheState, signals: WritebackSignalType[], opts?: {
|
|
18
|
+
userId?: string;
|
|
19
|
+
confidence?: number;
|
|
20
|
+
now?: string;
|
|
21
|
+
}): PendingWritebackCalibration[];
|
|
22
|
+
export declare function evaluateWritebackCalibrations(state: PsycheState): {
|
|
23
|
+
state: PsycheState;
|
|
24
|
+
feedback: WritebackCalibrationFeedback[];
|
|
25
|
+
};
|
|
26
|
+
export declare function applyWritebackSignals(state: PsycheState, signals: WritebackSignalType[], opts?: {
|
|
27
|
+
userId?: string;
|
|
28
|
+
confidence?: number;
|
|
29
|
+
now?: string;
|
|
30
|
+
}): PsycheState;
|
|
10
31
|
export declare function applyRelationalTurn(state: PsycheState, text: string, opts: {
|
|
11
32
|
mode?: PsycheMode;
|
|
12
33
|
now?: string;
|