psyche-ai 9.2.9 → 10.0.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 +24 -3
- package/dist/cli.js +8 -3
- package/dist/core.d.ts +4 -2
- package/dist/core.js +28 -31
- package/dist/diagnostics.d.ts +52 -1
- package/dist/diagnostics.js +248 -17
- package/dist/drives.d.ts +3 -3
- package/dist/drives.js +6 -6
- package/dist/generative-self.d.ts +1 -1
- package/dist/generative-self.js +9 -10
- package/dist/index.d.ts +9 -57
- package/dist/index.js +175 -60
- package/dist/observability.d.ts +14 -0
- package/dist/observability.js +392 -0
- package/dist/prompt.d.ts +23 -6
- package/dist/prompt.js +296 -140
- package/dist/psyche-file.js +18 -7
- package/dist/relation-dynamics.js +41 -19
- package/dist/types.d.ts +152 -6
- package/dist/types.js +5 -0
- package/llms.txt +19 -0
- package/openclaw.plugin.json +2 -2
- package/package.json +1 -1
- package/server.json +3 -3
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Psyche — 面向智能体的 AI-first 主观性内核
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/psyche-ai)
|
|
4
|
-
[]()
|
|
5
5
|
[]()
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
|
|
@@ -63,6 +63,11 @@ Psyche 要解决的不可压缩问题只有一个:
|
|
|
63
63
|
- `Oasyce Net = policy, operations, and resource orchestration`
|
|
64
64
|
- `Oasyce Chain = account truth, authorization truth, commitments, settlement, and public finality`
|
|
65
65
|
|
|
66
|
+
授权真相流也固定成单向:
|
|
67
|
+
`Chain -> Net -> Thronglets -> Psyche`
|
|
68
|
+
|
|
69
|
+
也就是说,`Psyche` 不判断“谁被授权”,它只读取已经成立的执行边界结果。
|
|
70
|
+
|
|
66
71
|
正式版本见:
|
|
67
72
|
|
|
68
73
|
- [docs/IDENTITY_MODEL.md](docs/IDENTITY_MODEL.md)
|
|
@@ -179,11 +184,17 @@ npx psyche-mcp --demo
|
|
|
179
184
|
|
|
180
185
|
## 30 秒安装
|
|
181
186
|
|
|
187
|
+
```bash
|
|
188
|
+
npm install psyche-ai
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
或者通过 OpenClaw 插件安装:
|
|
192
|
+
|
|
182
193
|
```bash
|
|
183
194
|
openclaw plugins install psyche-ai
|
|
184
195
|
```
|
|
185
196
|
|
|
186
|
-
|
|
197
|
+
验证:
|
|
187
198
|
|
|
188
199
|
```bash
|
|
189
200
|
openclaw plugins list | grep psyche
|
|
@@ -326,6 +337,16 @@ Psyche 现在更准确的目标,不是“模仿某种像人的风格”,而
|
|
|
326
337
|
|
|
327
338
|
当前主线里,`processInput()` 会直接返回 `replyEnvelope` 作为规范主接口;原有平级字段继续保留为兼容别名,避免打断现有宿主。`policyModifiers` 不再属于规范主接口,只保留为 legacy raw vector。
|
|
328
339
|
|
|
340
|
+
在这个规范主接口之外,`processInput()` 现在还会可选返回一个很薄的 `observability` side-channel。它不是新的控制面,也不会反向改写 `replyEnvelope`;它只回答五件事:
|
|
341
|
+
|
|
342
|
+
- 这轮当前由哪一个控制平面主导
|
|
343
|
+
- 当前 turn / writeback / session bridge / persisted relationship 四层是怎么对账的
|
|
344
|
+
- 这次 `work/private` 选择为什么会落在这个 profile 上
|
|
345
|
+
- 这轮和上一轮、session bridge、writeback、external continuity 之间的因果引用链是什么
|
|
346
|
+
- 当前 low-frequency external continuity 事件如何映射成 `localTraceRefs / signalRefs / traceRefs / summaryCandidateRefs`
|
|
347
|
+
|
|
348
|
+
这样别的 agent 或宿主不用再自己猜“现在到底是谁在主导”和“为什么这次选了这个策略”,但主链路仍然只有 `replyEnvelope` 一个真相源。
|
|
349
|
+
|
|
329
350
|
### 内在世界
|
|
330
351
|
|
|
331
352
|
Psyche 给 AI 一个始终运转的内在自我——不是条件触发,而是每时每刻都在:
|
|
@@ -547,7 +568,7 @@ Psyche 核心引擎永久开源(MIT)。
|
|
|
547
568
|
```bash
|
|
548
569
|
npm install
|
|
549
570
|
npm run build
|
|
550
|
-
npm test #
|
|
571
|
+
npm test # 1316 tests
|
|
551
572
|
npm run typecheck # strict mode
|
|
552
573
|
```
|
|
553
574
|
|
package/dist/cli.js
CHANGED
|
@@ -140,7 +140,7 @@ async function cmdInit(dir, mbti, name, lang, mode, traits, _noPersist) {
|
|
|
140
140
|
state.meta.mode = mode;
|
|
141
141
|
await saveState(absDir, state);
|
|
142
142
|
}
|
|
143
|
-
console.log(`\nPsyche initialized for ${state.meta.agentName} (${state.mbti})\n`);
|
|
143
|
+
console.log(`\nPsyche initialized for ${state.meta.agentName}${state.mbti ? ` (preset: ${state.mbti})` : ""}\n`);
|
|
144
144
|
printChemistry(state);
|
|
145
145
|
console.log(`\nFiles created:`);
|
|
146
146
|
console.log(` ${absDir}/psyche-state.json`);
|
|
@@ -165,7 +165,12 @@ async function cmdStatus(dir, json, userId) {
|
|
|
165
165
|
const emotion = describeEmotionalState(state.current, locale);
|
|
166
166
|
const hint = getExpressionHint(state.current, locale);
|
|
167
167
|
const elapsed = ((Date.now() - new Date(state.updatedAt).getTime()) / 60000).toFixed(1);
|
|
168
|
-
|
|
168
|
+
const baselineSummary = [
|
|
169
|
+
state.baseline.DA < 55 ? "introvert" : "extrovert",
|
|
170
|
+
state.baseline.DA > state.baseline.HT ? "intuitive" : "sensing",
|
|
171
|
+
state.baseline.OT >= 50 ? "feeling" : "thinking",
|
|
172
|
+
].join("/");
|
|
173
|
+
console.log(`\n${state.meta.agentName} (${baselineSummary}) — ${emotion}\n`);
|
|
169
174
|
printChemistry(state);
|
|
170
175
|
console.log();
|
|
171
176
|
printDrives(state);
|
|
@@ -264,7 +269,7 @@ async function cmdReset(dir, full) {
|
|
|
264
269
|
}
|
|
265
270
|
await saveState(absDir, state);
|
|
266
271
|
await generatePsycheMd(absDir, state);
|
|
267
|
-
console.log(`\n${state.meta.agentName} reset to baseline
|
|
272
|
+
console.log(`\n${state.meta.agentName} reset to baseline${full ? " [full reset including relationships]" : ""}\n`);
|
|
268
273
|
printChemistry(state);
|
|
269
274
|
console.log();
|
|
270
275
|
}
|
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, SessionBridgeState, ThrongletsExport, WritebackCalibrationFeedback, WritebackSignalType, ExternalContinuityEnvelope } from "./types.js";
|
|
1
|
+
import type { PsycheState, StimulusType, Locale, MBTIType, OutcomeScore, PsycheMode, PersonalityTraits, PolicyModifiers, ClassifierProvider, SubjectivityKernel, ResponseContract, GenerationControls, SessionBridgeState, ThrongletsExport, TurnObservability, WritebackCalibrationFeedback, WritebackSignalType, ExternalContinuityEnvelope } from "./types.js";
|
|
2
2
|
import type { StorageAdapter } from "./storage.js";
|
|
3
3
|
import type { DiagnosticReport, SessionMetrics } from "./diagnostics.js";
|
|
4
4
|
import type { ReplyEnvelope } from "./reply-envelope.js";
|
|
@@ -9,7 +9,7 @@ export interface PsycheEngineConfig {
|
|
|
9
9
|
stripUpdateTags?: boolean;
|
|
10
10
|
emotionalContagionRate?: number;
|
|
11
11
|
maxChemicalDelta?: number;
|
|
12
|
-
/** Compact mode
|
|
12
|
+
/** @deprecated Compact mode is always on since v10. This option is ignored. */
|
|
13
13
|
compactMode?: boolean;
|
|
14
14
|
/** Operating mode: "natural" (default), "work" (minimal emotions), "companion" (full emotions) */
|
|
15
15
|
mode?: PsycheMode;
|
|
@@ -57,6 +57,8 @@ export interface ProcessInputResult {
|
|
|
57
57
|
externalContinuity?: ExternalContinuityEnvelope<ThrongletsExport>;
|
|
58
58
|
/** v9.2.8: sparse low-frequency export surface suitable for Thronglets */
|
|
59
59
|
throngletsExports?: ThrongletsExport[];
|
|
60
|
+
/** v9.2.10: low-cost side channel for control boundary, state layers, and output attribution */
|
|
61
|
+
observability?: TurnObservability;
|
|
60
62
|
/**
|
|
61
63
|
* Legacy compatibility alias: ready-to-use prompt fragment summarizing raw policy modifiers.
|
|
62
64
|
*
|
package/dist/core.js
CHANGED
|
@@ -15,7 +15,7 @@ import { DEFAULT_RELATIONSHIP, DEFAULT_DRIVES, DEFAULT_LEARNING_STATE, DEFAULT_M
|
|
|
15
15
|
import { MemoryStorageAdapter } from "./storage.js";
|
|
16
16
|
import { applyDecay, applyStimulus, applyContagion, clamp, describeEmotionalState } from "./chemistry.js";
|
|
17
17
|
import { classifyStimulus, BuiltInClassifier, buildLLMClassifierPrompt, parseLLMClassification } from "./classify.js";
|
|
18
|
-
import {
|
|
18
|
+
import { buildCompactContext, buildProtocolContext } from "./prompt.js";
|
|
19
19
|
import { getSensitivity, getBaseline, getDefaultSelfModel, traitsToBaseline } from "./profiles.js";
|
|
20
20
|
import { isStimulusType } from "./guards.js";
|
|
21
21
|
import { parsePsycheUpdate, mergeUpdates, updateAgreementStreak, pushSnapshot, compressSession, summarizeTurnSemantic, } from "./psyche-file.js";
|
|
@@ -28,6 +28,7 @@ import { runReflectiveTurnPhases } from "./input-turn.js";
|
|
|
28
28
|
import { applyRelationalTurn, applySessionBridge, applyWritebackSignals, createWritebackCalibrations, evaluateWritebackCalibrations } from "./relation-dynamics.js";
|
|
29
29
|
import { buildExternalContinuityEnvelope } from "./external-continuity.js";
|
|
30
30
|
import { deriveThrongletsExports } from "./thronglets-export.js";
|
|
31
|
+
import { buildTurnObservability } from "./observability.js";
|
|
31
32
|
function formatWritebackFeedbackNote(feedback, locale) {
|
|
32
33
|
const top = feedback?.[0];
|
|
33
34
|
if (!top)
|
|
@@ -296,7 +297,7 @@ export class PsycheEngine {
|
|
|
296
297
|
};
|
|
297
298
|
}
|
|
298
299
|
// v9: Energy budget recovery during absence + depletion per turn
|
|
299
|
-
const isExtravert =
|
|
300
|
+
const isExtravert = state.baseline.DA >= 55;
|
|
300
301
|
const currentBudgets = state.energyBudgets ?? { ...DEFAULT_ENERGY_BUDGETS };
|
|
301
302
|
let energyBudgets = minutesElapsed >= 5
|
|
302
303
|
? computeEnergyRecovery(currentBudgets, minutesElapsed, isExtravert)
|
|
@@ -336,7 +337,7 @@ export class PsycheEngine {
|
|
|
336
337
|
const preStimulus = current;
|
|
337
338
|
// Feed drives from stimulus, then apply stimulus with drive-modified sensitivity
|
|
338
339
|
drives = feedDrives(drives, primary.type);
|
|
339
|
-
const effectiveSensitivity = computeEffectiveSensitivity(
|
|
340
|
+
const effectiveSensitivity = computeEffectiveSensitivity((state.sensitivity ?? 1.0), drives, primary.type, state.traitDrift);
|
|
340
341
|
// v9.2: Confidence modulates intensity — a 0.95 life-or-death dilemma
|
|
341
342
|
// hits ~1.7x harder than a 0.55 mild disagreement.
|
|
342
343
|
// Maps [0.5, 1.0] → [0.6, 1.2] via linear interpolation.
|
|
@@ -422,7 +423,7 @@ export class PsycheEngine {
|
|
|
422
423
|
// ── Generate prediction for next turn's auto-learning ────
|
|
423
424
|
if (appliedStimulus) {
|
|
424
425
|
const ctxHash = computeContextHash(state, opts?.userId);
|
|
425
|
-
const effectiveSensitivity = computeEffectiveSensitivity(
|
|
426
|
+
const effectiveSensitivity = computeEffectiveSensitivity((state.sensitivity ?? 1.0), state.drives, appliedStimulus, state.traitDrift);
|
|
426
427
|
const predicted = predictChemistry(preInteractionState.current, appliedStimulus, state.learning, ctxHash, effectiveSensitivity, this.cfg.maxChemicalDelta);
|
|
427
428
|
this.pendingPrediction = {
|
|
428
429
|
predictedChemistry: predicted,
|
|
@@ -479,30 +480,24 @@ export class PsycheEngine {
|
|
|
479
480
|
subjectivityContext: derivedReplyEnvelope.subjectivityContext,
|
|
480
481
|
responseContractContext: derivedReplyEnvelope.responseContractContext,
|
|
481
482
|
policyContext: derivedReplyEnvelope.policyContext || undefined,
|
|
483
|
+
sessionBridge,
|
|
482
484
|
};
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
sessionBridge,
|
|
496
|
-
writebackFeedback,
|
|
497
|
-
externalContinuity,
|
|
498
|
-
throngletsExports,
|
|
499
|
-
policyContext: derivedReplyEnvelope.policyContext,
|
|
500
|
-
};
|
|
501
|
-
}
|
|
485
|
+
const observability = buildTurnObservability(state, {
|
|
486
|
+
replyEnvelope,
|
|
487
|
+
promptRenderInputs,
|
|
488
|
+
compactMode: this.cfg.compactMode,
|
|
489
|
+
stimulus: appliedStimulus,
|
|
490
|
+
userText: text || undefined,
|
|
491
|
+
sessionBridge,
|
|
492
|
+
writebackFeedback,
|
|
493
|
+
relationContext: relationalTurn.relationContext,
|
|
494
|
+
externalContinuityEvents: throngletsExports,
|
|
495
|
+
});
|
|
496
|
+
// v10: compact mode is always on. Legacy buildDynamicContext removed from engine path.
|
|
502
497
|
const externalContinuity = buildExternalContinuityEnvelope(throngletsExports);
|
|
503
498
|
return {
|
|
504
|
-
systemContext:
|
|
505
|
-
dynamicContext:
|
|
499
|
+
systemContext: "",
|
|
500
|
+
dynamicContext: buildCompactContext(state, opts?.userId, promptRenderInputs),
|
|
506
501
|
stimulus: appliedStimulus,
|
|
507
502
|
stimulusConfidence: this.lastStimulusAssessment?.confidence,
|
|
508
503
|
replyEnvelope,
|
|
@@ -514,6 +509,7 @@ export class PsycheEngine {
|
|
|
514
509
|
writebackFeedback,
|
|
515
510
|
externalContinuity,
|
|
516
511
|
throngletsExports,
|
|
512
|
+
observability,
|
|
517
513
|
policyContext: derivedReplyEnvelope.policyContext,
|
|
518
514
|
};
|
|
519
515
|
}
|
|
@@ -545,7 +541,7 @@ export class PsycheEngine {
|
|
|
545
541
|
const selfFeedbackRate = 0.3;
|
|
546
542
|
state = {
|
|
547
543
|
...state,
|
|
548
|
-
current: applyContagion(state.current, selfPrimary.type, selfFeedbackRate,
|
|
544
|
+
current: applyContagion(state.current, selfPrimary.type, selfFeedbackRate, (state.sensitivity ?? 1.0)),
|
|
549
545
|
};
|
|
550
546
|
stateChanged = true;
|
|
551
547
|
// v9.2 P4: Autonomic recovery — expressing vulnerable/comforting emotions
|
|
@@ -588,7 +584,7 @@ export class PsycheEngine {
|
|
|
588
584
|
...state,
|
|
589
585
|
drives: feedDrives(state.drives, parseResult.llmStimulus),
|
|
590
586
|
};
|
|
591
|
-
const effectiveSensitivity = computeEffectiveSensitivity(
|
|
587
|
+
const effectiveSensitivity = computeEffectiveSensitivity((state.sensitivity ?? 1.0), state.drives, parseResult.llmStimulus, state.traitDrift);
|
|
592
588
|
state = {
|
|
593
589
|
...state,
|
|
594
590
|
current: applyStimulus(state.current, parseResult.llmStimulus, effectiveSensitivity * (overrideAllowed && this._lastAlgorithmApplied ? 0.8 : 1), this.cfg.maxChemicalDelta, NOOP_LOGGER),
|
|
@@ -772,14 +768,15 @@ export class PsycheEngine {
|
|
|
772
768
|
}
|
|
773
769
|
createDefaultState() {
|
|
774
770
|
const { mbti, name, locale } = this.cfg;
|
|
775
|
-
// Use Big Five traits if provided, otherwise use
|
|
771
|
+
// Use Big Five traits if provided, otherwise use preset baseline
|
|
776
772
|
const baseline = this.traits ? traitsToBaseline(this.traits).baseline : getBaseline(mbti);
|
|
773
|
+
const sensitivity = this.traits ? 1.0 : getSensitivity(mbti);
|
|
777
774
|
const selfModel = getDefaultSelfModel(mbti);
|
|
778
775
|
const now = new Date().toISOString();
|
|
779
776
|
return {
|
|
780
|
-
version:
|
|
781
|
-
mbti,
|
|
777
|
+
version: 10,
|
|
782
778
|
baseline,
|
|
779
|
+
sensitivity,
|
|
783
780
|
current: { ...baseline },
|
|
784
781
|
drives: { ...DEFAULT_DRIVES },
|
|
785
782
|
updatedAt: now,
|
|
@@ -824,7 +821,7 @@ export class PsycheEngine {
|
|
|
824
821
|
*/
|
|
825
822
|
async resetState(opts) {
|
|
826
823
|
let state = this.ensureInitialized();
|
|
827
|
-
const baseline = this.traits ? traitsToBaseline(this.traits).baseline :
|
|
824
|
+
const baseline = this.traits ? traitsToBaseline(this.traits).baseline : { ...state.baseline };
|
|
828
825
|
state = {
|
|
829
826
|
...state,
|
|
830
827
|
current: { ...baseline },
|
package/dist/diagnostics.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import type { AppraisalAxes, PsycheState, ChemicalState, StimulusType, InnateDrives } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The four diagnostic layers, matching the frozen stack.
|
|
4
|
+
* When something breaks, the first question is: which layer?
|
|
5
|
+
*/
|
|
6
|
+
export type DiagnosticLayer = "subjective-continuity" | "delegate-continuity" | "policy-orchestration" | "public-truth";
|
|
2
7
|
export type Severity = "critical" | "warning" | "info";
|
|
3
8
|
export interface DiagnosticIssue {
|
|
4
9
|
id: string;
|
|
5
10
|
severity: Severity;
|
|
11
|
+
/** Which stack layer this issue belongs to */
|
|
12
|
+
layer: DiagnosticLayer;
|
|
6
13
|
message: string;
|
|
7
14
|
detail?: string;
|
|
8
15
|
/** Dev-facing: what to fix in our code or config */
|
|
@@ -40,8 +47,12 @@ export interface DiagnosticReport {
|
|
|
40
47
|
version: string;
|
|
41
48
|
timestamp: string;
|
|
42
49
|
agent: string;
|
|
43
|
-
mbti
|
|
50
|
+
mbti?: string;
|
|
44
51
|
issues: DiagnosticIssue[];
|
|
52
|
+
/** Issues grouped by stack layer — same issues as `issues`, partitioned */
|
|
53
|
+
layeredIssues: Record<DiagnosticLayer, DiagnosticIssue[]>;
|
|
54
|
+
/** Per-layer health summary — the first thing to read when something is wrong */
|
|
55
|
+
layerHealth: LayerHealthSummary;
|
|
45
56
|
metrics: SessionMetrics;
|
|
46
57
|
stateSnapshot: {
|
|
47
58
|
chemistry: ChemicalState;
|
|
@@ -54,7 +65,47 @@ export interface DiagnosticReport {
|
|
|
54
65
|
stateVersion: number;
|
|
55
66
|
};
|
|
56
67
|
}
|
|
68
|
+
export type LayerStatus = "healthy" | "degraded" | "failing";
|
|
69
|
+
export interface LayerHealthDetail {
|
|
70
|
+
status: LayerStatus;
|
|
71
|
+
/** Worst severity found in this layer (null = no issues) */
|
|
72
|
+
worstSeverity: Severity | null;
|
|
73
|
+
issueCount: number;
|
|
74
|
+
/** One-line human-readable summary */
|
|
75
|
+
summary: string;
|
|
76
|
+
}
|
|
77
|
+
export interface LayerHealthSummary {
|
|
78
|
+
"subjective-continuity": LayerHealthDetail & {
|
|
79
|
+
/** Chemistry deviation from baseline (0 = identical) */
|
|
80
|
+
chemistryDeviation: number;
|
|
81
|
+
/** Session bridge present and carrying identity state */
|
|
82
|
+
sessionBridgeActive: boolean;
|
|
83
|
+
/** Trait drift trajectory established */
|
|
84
|
+
traitDriftEstablished: boolean;
|
|
85
|
+
/** Number of active dyadic relations */
|
|
86
|
+
activeDyadicRelations: number;
|
|
87
|
+
/** Average prediction error (0-1, lower = better calibrated) */
|
|
88
|
+
predictionError: number;
|
|
89
|
+
};
|
|
90
|
+
"delegate-continuity": LayerHealthDetail & {
|
|
91
|
+
/** External continuity contract connected */
|
|
92
|
+
externalContinuityConnected: boolean;
|
|
93
|
+
/** Number of pending exports waiting for Thronglets */
|
|
94
|
+
pendingExports: number;
|
|
95
|
+
/** Writeback calibration loop active */
|
|
96
|
+
writebackLoopActive: boolean;
|
|
97
|
+
/** Last calibration effect breakdown */
|
|
98
|
+
calibrationEffects: {
|
|
99
|
+
converging: number;
|
|
100
|
+
holding: number;
|
|
101
|
+
diverging: number;
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
"policy-orchestration": LayerHealthDetail;
|
|
105
|
+
"public-truth": LayerHealthDetail;
|
|
106
|
+
}
|
|
57
107
|
export declare function runHealthCheck(state: PsycheState): DiagnosticIssue[];
|
|
108
|
+
export declare function computeLayerHealthSummary(state: PsycheState, issues: DiagnosticIssue[]): LayerHealthSummary;
|
|
58
109
|
export declare class DiagnosticCollector {
|
|
59
110
|
private metrics;
|
|
60
111
|
private prevChemistry;
|