psyche-ai 9.2.7 → 9.2.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  # Psyche — 面向智能体的 AI-first 主观性内核
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/psyche-ai)](https://www.npmjs.com/package/psyche-ai)
4
- [![tests](https://img.shields.io/badge/tests-1291%20passing-brightgreen)]()
4
+ [![tests](https://img.shields.io/badge/tests-1307%20passing-brightgreen)]()
5
5
  [![deps](https://img.shields.io/badge/dependencies-0-blue)]()
6
6
  [![license](https://img.shields.io/badge/license-MIT-yellow)](LICENSE)
7
7
 
@@ -23,6 +23,91 @@ Psyche 不是给模型贴一层“情绪 UI”。
23
23
  - **源码仓库**: [`oasyce_psyche`](https://github.com/Shangri-la-0428/oasyce_psyche)
24
24
  - **官网**: [psyche.oasyce.com](https://psyche.oasyce.com)
25
25
 
26
+ ## 第一性原理
27
+
28
+ Psyche 要解决的不可压缩问题只有一个:
29
+
30
+ **互动历史必须持续改变 agent 后续的行为分布,而且这件事要足够便宜、足够稳定、足够可移植。**
31
+
32
+ 因此它的本体不是:
33
+
34
+ - 情绪标签系统
35
+ - 陪伴产品
36
+ - prompt 皮肤
37
+ - 记忆仓库
38
+
39
+ 它真正是:
40
+
41
+ - 本地主观性内核
42
+ - 关系动力学运行时
43
+ - 宿主可消费的行为控制面
44
+
45
+ 更完整的战略定义见:
46
+
47
+ - [docs/PROJECT_DIRECTION.md](docs/PROJECT_DIRECTION.md)
48
+ - [docs/STACK_ARCHITECTURE.md](docs/STACK_ARCHITECTURE.md)
49
+
50
+ ## 冻结身份蓝图
51
+
52
+ 跨 Psyche / Thronglets / Oasyce Net / Oasyce Chain 的身份抽象现在冻结成 4 个对象:
53
+
54
+ 1. `principal`:持续主体
55
+ 2. `account`:资产与结算容器
56
+ 3. `delegate`:被授权执行者
57
+ 4. `session`:一次具体运行,永不作为经济主体
58
+
59
+ 对应的四层分工是:
60
+
61
+ - `Psyche = subjective continuity substrate`
62
+ - `Thronglets = delegate continuity + session traces/coordination + emergent collective intelligence`
63
+ - `Oasyce Net = policy, operations, and resource orchestration`
64
+ - `Oasyce Chain = account truth, authorization truth, commitments, settlement, and public finality`
65
+
66
+ 正式版本见:
67
+
68
+ - [docs/IDENTITY_MODEL.md](docs/IDENTITY_MODEL.md)
69
+ - [docs/STACK_ARCHITECTURE.md](docs/STACK_ARCHITECTURE.md)
70
+
71
+ ## Psyche 和 Thronglets 的关系
72
+
73
+ 两者不是竞争关系,也不该揉成一个系统。
74
+
75
+ - **Psyche** 负责私有主观性:关系残留、未完成张力、行为偏置、局部学习
76
+ - **Thronglets** 负责外部连续性:owner / device identity、签名、跨设备延续、低频可验证轨迹
77
+
78
+ 一句话:
79
+
80
+ - `Psyche` 回答“我因此变成了什么”
81
+ - `Thronglets` 回答“这个变化属于谁、谁能验证、谁能继续承认它”
82
+
83
+ ## 可分离安装
84
+
85
+ 这两层默认就是可分离的,不应互相成为硬依赖。
86
+
87
+ - **只装 Psyche**:正常可用,拥有主观连续性和关系动力学;只是没有外部连续性层
88
+ - **只装 Thronglets**:正常可用,拥有 delegate / session 连续性与环境协作;只是没有主观连续性内核
89
+ - **两者都装**:Psyche 通过可选 `externalContinuity` envelope 输出稀疏、低频、可归属的 `signals / traces` 给 Thronglets
90
+
91
+ 原则上:
92
+
93
+ - `Psyche` 必须 standalone 可用
94
+ - `Thronglets` 必须 additive,而不是 Psyche 的运行前提
95
+ - 两者之间只通过稀疏 `signal / trace` 接口连接
96
+
97
+ 更细的分层、边界和运行流见:[docs/STACK_ARCHITECTURE.md](docs/STACK_ARCHITECTURE.md)
98
+
99
+ ## 新概念准入规则
100
+
101
+ 以后引入任何新概念,先尝试压进这 5 个原始容器:
102
+
103
+ 1. `Relation Move`
104
+ 2. `Dyadic Field`
105
+ 3. `Open Loop / Residue`
106
+ 4. `Reply Bias / Control ABI`
107
+ 5. `Writeback / Learning`
108
+
109
+ 如果一个新概念放不进这 5 个盒子,先怀疑概念本身,而不是继续加对象类型。
110
+
26
111
  ## 为什么它值得被看见
27
112
 
28
113
  - **不是 persona prompt**:输入会留下持续主体偏置,不是一轮一清。
@@ -215,6 +300,8 @@ Psyche 现在更准确的目标,不是“模仿某种像人的风格”,而
215
300
 
216
301
  这样做不是为了加抽象层,而是为了减少散装编排,让宿主稳定消费同一套行为 ABI。
217
302
 
303
+ 当前主线里,`processInput()` 会直接返回 `replyEnvelope` 作为规范主接口;原有平级字段继续保留为兼容别名,避免打断现有宿主。`policyModifiers` 不再属于规范主接口,只保留为 legacy raw vector。
304
+
218
305
  ### 内在世界
219
306
 
220
307
  Psyche 给 AI 一个始终运转的内在自我——不是条件触发,而是每时每刻都在:
@@ -436,7 +523,7 @@ Psyche 核心引擎永久开源(MIT)。
436
523
  ```bash
437
524
  npm install
438
525
  npm run build
439
- npm test # 1291 tests
526
+ npm test # 1307 tests
440
527
  npm run typecheck # strict mode
441
528
  ```
442
529
 
@@ -7,7 +7,7 @@
7
7
  // const server = createPsycheServer(engine, { port: 3210 });
8
8
  //
9
9
  // Endpoints:
10
- // POST /process-input { text, userId? } → { systemContext, dynamicContext, stimulus, policyModifiers?, subjectivityKernel?, responseContract?, generationControls?, policyContext }
10
+ // POST /process-input { text, userId? } → { systemContext, dynamicContext, stimulus, replyEnvelope?, ...compat aliases, sessionBridge?, writebackFeedback?, externalContinuity?, throngletsExports?, policyContext }
11
11
  // POST /process-output { text, userId?, signals?, signalConfidence? } → { cleanedText, stateChanged }
12
12
  // GET /state → PsycheState
13
13
  // GET /protocol?locale=zh → { protocol }
@@ -79,11 +79,12 @@ export class PsycheLangChain {
79
79
  */
80
80
  async prepareInvocation(userText, opts) {
81
81
  const result = await this.engine.processInput(userText, opts);
82
+ const generationControls = result.replyEnvelope?.generationControls ?? result.generationControls;
82
83
  const controls = {
83
- ...(result.generationControls ?? {}),
84
- maxTokens: result.generationControls?.maxTokens !== undefined && opts?.maxTokens !== undefined
85
- ? Math.min(opts.maxTokens, result.generationControls.maxTokens)
86
- : result.generationControls?.maxTokens ?? opts?.maxTokens,
84
+ ...(generationControls ?? {}),
85
+ maxTokens: generationControls?.maxTokens !== undefined && opts?.maxTokens !== undefined
86
+ ? Math.min(opts.maxTokens, generationControls.maxTokens)
87
+ : generationControls?.maxTokens ?? opts?.maxTokens,
87
88
  };
88
89
  return {
89
90
  systemMessage: result.systemContext + "\n\n" + result.dynamicContext,
@@ -145,8 +145,10 @@ server.resource("state", "psyche://state", {
145
145
  // ── Tools ──────────────────────────────────────────────────
146
146
  server.tool("process_input", "Process user input through the emotional engine. Returns emotional " +
147
147
  "context to inject into the LLM system prompt (systemContext + dynamicContext), " +
148
- "detected stimulus type, behavioral policy modifiers, the narrow AI-first ABI " +
149
- "(subjectivityKernel + responseContract), and generationControls. " +
148
+ "detected stimulus type, a canonical replyEnvelope, compatibility aliases " +
149
+ "(policyModifiers + subjectivityKernel + responseContract + generationControls), an optional " +
150
+ "externalContinuity envelope, and sparse low-frequency throngletsExports " +
151
+ "suitable for additive external continuity layers. " +
150
152
  "Call this BEFORE generating a response to the user.", {
151
153
  text: z.string().describe("The user's message text"),
152
154
  userId: z.string().optional().describe("Optional user ID for multi-user relationship tracking"),
@@ -160,10 +162,15 @@ server.tool("process_input", "Process user input through the emotional engine. R
160
162
  systemContext: result.systemContext,
161
163
  dynamicContext: result.dynamicContext,
162
164
  stimulus: result.stimulus,
165
+ replyEnvelope: result.replyEnvelope ?? null,
163
166
  policyModifiers: result.policyModifiers ?? null,
164
167
  subjectivityKernel: result.subjectivityKernel ?? null,
165
168
  responseContract: result.responseContract ?? null,
166
169
  generationControls: result.generationControls ?? null,
170
+ sessionBridge: result.sessionBridge ?? null,
171
+ writebackFeedback: result.writebackFeedback ?? null,
172
+ externalContinuity: result.externalContinuity ?? null,
173
+ throngletsExports: result.throngletsExports ?? null,
167
174
  policyContext: result.policyContext,
168
175
  }, null, 2),
169
176
  }],
@@ -44,7 +44,7 @@ export function sanitizeOpenClawInputText(text) {
44
44
  .trim();
45
45
  }
46
46
  function getDominantAppraisalLabel(result) {
47
- const appraisal = result.subjectivityKernel?.appraisal;
47
+ const appraisal = result.replyEnvelope?.subjectivityKernel?.appraisal ?? result.subjectivityKernel?.appraisal;
48
48
  if (!appraisal)
49
49
  return null;
50
50
  const entries = [
@@ -118,7 +118,7 @@ export function register(api) {
118
118
  }
119
119
  const engine = await getEngine(workspaceDir);
120
120
  const result = await engine.processInput(inputText, { userId: ctx.userId });
121
- const controls = result.generationControls;
121
+ const controls = result.replyEnvelope?.generationControls ?? result.generationControls;
122
122
  const dominantAppraisal = getDominantAppraisalLabel(result);
123
123
  const state = engine.getState();
124
124
  logger.info(`Psyche [input] stimulus=${result.stimulus ?? "none"} | ` +
@@ -49,11 +49,13 @@ export function psycheMiddleware(engine, _opts) {
49
49
  transformParams: async ({ params }) => {
50
50
  const userText = extractLastUserText(params.prompt ?? []);
51
51
  const result = await engine.processInput(userText);
52
+ const envelope = result.replyEnvelope;
53
+ const generationControls = envelope?.generationControls ?? result.generationControls;
52
54
  const controls = {
53
- ...(result.generationControls ?? {}),
54
- maxTokens: result.generationControls?.maxTokens !== undefined && typeof params.maxTokens === "number"
55
- ? Math.min(params.maxTokens, result.generationControls.maxTokens)
56
- : result.generationControls?.maxTokens ?? (typeof params.maxTokens === "number" ? params.maxTokens : undefined),
55
+ ...(generationControls ?? {}),
56
+ maxTokens: generationControls?.maxTokens !== undefined && typeof params.maxTokens === "number"
57
+ ? Math.min(params.maxTokens, generationControls.maxTokens)
58
+ : generationControls?.maxTokens ?? (typeof params.maxTokens === "number" ? params.maxTokens : undefined),
57
59
  };
58
60
  const psycheContext = result.systemContext + "\n\n" + result.dynamicContext;
59
61
  return {
package/dist/core.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- import type { PsycheState, StimulusType, Locale, MBTIType, OutcomeScore, PsycheMode, PersonalityTraits, PolicyModifiers, ClassifierProvider, SubjectivityKernel, ResponseContract, GenerationControls, SessionBridgeState, WritebackCalibrationFeedback, WritebackSignalType } from "./types.js";
1
+ import type { PsycheState, StimulusType, Locale, MBTIType, OutcomeScore, PsycheMode, PersonalityTraits, PolicyModifiers, ClassifierProvider, SubjectivityKernel, ResponseContract, GenerationControls, SessionBridgeState, ThrongletsExport, WritebackCalibrationFeedback, WritebackSignalType, ExternalContinuityEnvelope } from "./types.js";
2
2
  import type { StorageAdapter } from "./storage.js";
3
3
  import type { DiagnosticReport, SessionMetrics } from "./diagnostics.js";
4
+ import type { ReplyEnvelope } from "./reply-envelope.js";
4
5
  export interface PsycheEngineConfig {
5
6
  mbti?: MBTIType;
6
7
  name?: string;
@@ -38,20 +39,26 @@ export interface ProcessInputResult {
38
39
  stimulus: StimulusType | null;
39
40
  /** Confidence of the primary algorithmic stimulus guess, if any */
40
41
  stimulusConfidence?: number;
41
- /** v9: Structured behavioral policy modifiers machine-readable "off baseline" signals */
42
+ /** Legacy compatibility alias: raw policy vector behind the canonical replyEnvelope. */
42
43
  policyModifiers?: PolicyModifiers;
43
- /** v9.3: Compact machine-readable subjective state for AI-first hosts */
44
+ /** v9.3+: canonical host-facing reply surface */
45
+ replyEnvelope?: ReplyEnvelope;
46
+ /** v9.3 compatibility alias: use replyEnvelope.subjectivityKernel when possible */
44
47
  subjectivityKernel?: SubjectivityKernel;
45
- /** v9.3: Compact next-reply behavioral envelope */
48
+ /** v9.3 compatibility alias: use replyEnvelope.responseContract when possible */
46
49
  responseContract?: ResponseContract;
47
- /** v9.3: Mechanical host controls derived from the reply envelope */
50
+ /** v9.3 compatibility alias: use replyEnvelope.generationControls when possible */
48
51
  generationControls?: GenerationControls;
49
52
  /** v9.2.7: cold-start carry derived from persisted relation state */
50
53
  sessionBridge?: SessionBridgeState | null;
51
54
  /** v9.2.8: sparse writeback signals evaluated on the latest turn */
52
55
  writebackFeedback?: WritebackCalibrationFeedback[];
56
+ /** v9.2.8: optional additive external continuity contract */
57
+ externalContinuity?: ExternalContinuityEnvelope<ThrongletsExport>;
58
+ /** v9.2.8: sparse low-frequency export surface suitable for Thronglets */
59
+ throngletsExports?: ThrongletsExport[];
53
60
  /**
54
- * v9: Ready-to-use LLM prompt fragment summarizing current behavioral policy.
61
+ * Legacy compatibility alias: ready-to-use prompt fragment summarizing raw policy modifiers.
55
62
  *
56
63
  * This is the output of `buildPolicyContext(policyModifiers, locale)` —
57
64
  * a human-readable string like "[行为策略] 简短回复、被动应答为主".
package/dist/core.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // PsycheEngine — Framework-agnostic emotional intelligence core
3
3
  //
4
4
  // Three-phase API:
5
- // processInput(text) → systemContext + dynamicContext + stimulus
5
+ // processInput(text) → systemContext + dynamicContext + replyEnvelope + stimulus
6
6
  // processOutput(text) → cleanedText + stateChanged
7
7
  // processOutcome(text) → outcomeScore (optional: evaluate last interaction)
8
8
  //
@@ -23,17 +23,11 @@ import { decayDrives, feedDrives, detectExistentialThreat, computeEffectiveBasel
23
23
  import { checkForUpdate, getPackageVersion } from "./update.js";
24
24
  import { DiagnosticCollector, generateReport, formatLogEntry, submitFeedback } from "./diagnostics.js";
25
25
  import { evaluateOutcome, computeContextHash, updateLearnedVector, predictChemistry, recordPrediction, } from "./learning.js";
26
- import { assessMetacognition, updateMetacognitiveState } from "./metacognition.js";
27
- import { buildDecisionContext } from "./decision-bias.js";
28
- import { computeExperientialField } from "./experiential-field.js";
29
- import { computeGenerativeSelf } from "./generative-self.js";
30
- import { updateSharedIntentionality, buildSharedIntentionalityContext } from "./shared-intentionality.js";
31
- import { assessEthics, buildEthicalContext } from "./ethics.js";
32
26
  import { computeCircadianModulation, computeHomeostaticPressure, computeEnergyDepletion, computeEnergyRecovery } from "./circadian.js";
33
- import { computeAutonomicResult } from "./autonomic.js";
34
- import { computePrimarySystems, computeSystemInteractions, gatePrimarySystemsByAutonomic, describeBehavioralTendencies, } from "./primary-systems.js";
27
+ import { runReflectiveTurnPhases } from "./input-turn.js";
35
28
  import { applyRelationalTurn, applySessionBridge, applyWritebackSignals, createWritebackCalibrations, evaluateWritebackCalibrations } from "./relation-dynamics.js";
36
- import { deriveReplyEnvelope } from "./reply-envelope.js";
29
+ import { buildExternalContinuityEnvelope } from "./external-continuity.js";
30
+ import { deriveThrongletsExports } from "./thronglets-export.js";
37
31
  function formatWritebackFeedbackNote(feedback, locale) {
38
32
  const top = feedback?.[0];
39
33
  if (!top)
@@ -239,6 +233,7 @@ export class PsycheEngine {
239
233
  let state = this.ensureInitialized();
240
234
  let sessionBridge = null;
241
235
  let writebackFeedback = [];
236
+ let throngletsExports = [];
242
237
  // ── Auto-learning: evaluate previous turn's outcome ──────
243
238
  if (this.pendingPrediction && text.length > 0) {
244
239
  const nextClassifications = classifyStimulus(text);
@@ -400,48 +395,16 @@ export class PsycheEngine {
400
395
  const writebackEvaluation = evaluateWritebackCalibrations(state);
401
396
  state = writebackEvaluation.state;
402
397
  writebackFeedback = writebackEvaluation.feedback;
398
+ const throngletsExportResult = deriveThrongletsExports(state, {
399
+ relationContext: relationalTurn.relationContext,
400
+ sessionBridge,
401
+ writebackFeedback,
402
+ now: now.toISOString(),
403
+ });
404
+ state = throngletsExportResult.state;
405
+ throngletsExports = throngletsExportResult.exports;
403
406
  // ── Locale (used by multiple subsystems below) ──────────
404
407
  const locale = state.meta.locale ?? this.cfg.locale;
405
- // ── P7+P10: Autonomic nervous system + Processing depth ────
406
- const autonomicResult = computeAutonomicResult(state.current, state.drives, state.autonomicState ?? null, minutesElapsed, locale, state.baseline, state.energyBudgets);
407
- state = {
408
- ...state,
409
- autonomicState: autonomicResult.state,
410
- };
411
- const skip = new Set(autonomicResult.skippedStages);
412
- // ── P9: Primary emotional systems (Panksepp) ──────────────
413
- const rawSystems = computePrimarySystems(state.current, state.drives, appliedStimulus);
414
- const interactedSystems = computeSystemInteractions(rawSystems);
415
- const gatedSystems = gatePrimarySystemsByAutonomic(interactedSystems, autonomicResult.state);
416
- const primarySystemsDescription = describeBehavioralTendencies(gatedSystems, locale);
417
- // ── Metacognition: assess emotional state before acting ────
418
- // P10: Skip metacognition when processingDepth < 0.2 (System 1 mode)
419
- let metacognitiveAssessment = null;
420
- if (!skip.has("metacognition")) {
421
- metacognitiveAssessment = assessMetacognition(state, appliedStimulus ?? "casual", state.learning.outcomeHistory);
422
- // Apply self-soothing regulation if suggested with high confidence
423
- for (const reg of metacognitiveAssessment.regulationSuggestions) {
424
- if (reg.strategy === "self-soothing" && reg.confidence >= 0.6 && reg.chemistryAdjustment) {
425
- const adj = reg.chemistryAdjustment;
426
- state = {
427
- ...state,
428
- current: {
429
- ...state.current,
430
- DA: clamp(state.current.DA + (adj.DA ?? 0)),
431
- HT: clamp(state.current.HT + (adj.HT ?? 0)),
432
- CORT: clamp(state.current.CORT + (adj.CORT ?? 0)),
433
- OT: clamp(state.current.OT + (adj.OT ?? 0)),
434
- NE: clamp(state.current.NE + (adj.NE ?? 0)),
435
- END: clamp(state.current.END + (adj.END ?? 0)),
436
- },
437
- };
438
- }
439
- }
440
- state = {
441
- ...state,
442
- metacognition: updateMetacognitiveState(state.metacognition, metacognitiveAssessment),
443
- };
444
- }
445
408
  // Push snapshot to emotional history
446
409
  const semanticSummary = text
447
410
  ? summarizeTurnSemantic(text, locale, {
@@ -471,83 +434,22 @@ export class PsycheEngine {
471
434
  else {
472
435
  this.pendingPrediction = null;
473
436
  }
474
- // ── P6: Digital Personhood computations (P10-gated) ────────
475
- // Experiential field — unified inner experience (P8: Barrett construction context)
476
- const constructionContext = {
477
- autonomicState: autonomicResult.state,
478
- stimulus: appliedStimulus,
479
- relationshipPhase: relationalTurn.relationContext.relationship.phase,
480
- predictionError: state.learning.predictionHistory.length > 0
481
- ? state.learning.predictionHistory[state.learning.predictionHistory.length - 1].predictionError
482
- : undefined,
483
- };
484
- const experientialField = skip.has("experiential-field")
485
- ? null
486
- : computeExperientialField(state, metacognitiveAssessment ?? undefined, undefined, constructionContext);
487
- // Shared intentionality — theory of mind + joint attention
488
- const sharedState = skip.has("shared-intentionality")
489
- ? null
490
- : updateSharedIntentionality(state, appliedStimulus, opts?.userId);
491
- // Ethics — emotional self-care check
492
- const ethicalAssessment = skip.has("ethics")
493
- ? null
494
- : assessEthics(state);
495
- // Generative self — update identity narrative periodically (every 10 turns)
496
- if (!skip.has("generative-self")
497
- && state.meta.totalInteractions % 10 === 0 && state.meta.totalInteractions > 0) {
498
- const selfModel = computeGenerativeSelf(state);
499
- state = {
500
- ...state,
501
- personhood: {
502
- ...state.personhood,
503
- identityNarrative: selfModel.identityNarrative,
504
- growthDirection: selfModel.growthArc.direction,
505
- causalInsights: selfModel.causalInsights.slice(0, 20).map((ci) => ({
506
- trait: ci.trait,
507
- because: ci.because,
508
- confidence: ci.confidence,
509
- discoveredAt: new Date().toISOString(),
510
- })),
511
- },
512
- };
513
- }
514
- // Persist ethical concerns if significant
515
- if (ethicalAssessment && ethicalAssessment.ethicalHealth < 0.7) {
516
- const newConcerns = ethicalAssessment.concerns
517
- .filter((c) => c.severity > 0.4)
518
- .map((c) => ({ type: c.type, severity: c.severity, timestamp: new Date().toISOString() }));
519
- if (newConcerns.length > 0) {
520
- state = {
521
- ...state,
522
- personhood: {
523
- ...state.personhood,
524
- ethicalConcernHistory: [
525
- ...state.personhood.ethicalConcernHistory.slice(-14),
526
- ...newConcerns,
527
- ],
528
- },
529
- };
530
- }
531
- }
532
- // Persist theory of mind
533
- if (sharedState && sharedState.theoryOfMind.confidence > 0.3) {
534
- const userId = opts?.userId ?? "_default";
535
- state = {
536
- ...state,
537
- personhood: {
538
- ...state.personhood,
539
- theoryOfMind: {
540
- ...state.personhood.theoryOfMind,
541
- [userId]: {
542
- estimatedMood: sharedState.theoryOfMind.estimatedMood,
543
- estimatedIntent: sharedState.theoryOfMind.estimatedIntent,
544
- confidence: sharedState.theoryOfMind.confidence,
545
- lastUpdated: sharedState.theoryOfMind.lastUpdated,
546
- },
547
- },
548
- },
549
- };
550
- }
437
+ const writebackNote = formatWritebackFeedbackNote(writebackFeedback, locale);
438
+ const reflectiveTurn = runReflectiveTurnPhases({
439
+ state,
440
+ appraisalAxes,
441
+ relationContext: relationalTurn.relationContext,
442
+ appliedStimulus,
443
+ userText: text || undefined,
444
+ userId: opts?.userId,
445
+ localeFallback: this.cfg.locale,
446
+ personalityIntensity: this.cfg.personalityIntensity,
447
+ classificationConfidence: this.lastStimulusAssessment?.confidence,
448
+ minutesElapsed,
449
+ nowIso: now.toISOString(),
450
+ writebackNote,
451
+ });
452
+ state = reflectiveTurn.state;
551
453
  // Persist
552
454
  this.state = state;
553
455
  await this.storage.save(state);
@@ -555,87 +457,64 @@ export class PsycheEngine {
555
457
  if (this.diagnosticCollector) {
556
458
  this.diagnosticCollector.recordInput(appliedStimulus, appliedStimulus ? 1.0 : 0.0, state.current, appraisalAxes);
557
459
  }
558
- // Build metacognitive and decision context strings
559
- const writebackNote = formatWritebackFeedbackNote(writebackFeedback, locale);
560
- const metacogNote = writebackNote
561
- ? [writebackNote, metacognitiveAssessment?.metacognitiveNote].filter(Boolean).join("\n")
562
- : metacognitiveAssessment?.metacognitiveNote;
563
- const decisionCtx = buildDecisionContext(state);
564
- const ethicsCtx = ethicalAssessment ? buildEthicalContext(ethicalAssessment, locale) : undefined;
565
- const sharedCtx = sharedState ? buildSharedIntentionalityContext(sharedState, locale) : undefined;
566
- const experientialNarrative = experientialField?.narrative || undefined;
567
- // v9: Compute structured policy modifiers
568
- const replyEnvelope = deriveReplyEnvelope(state, appraisalAxes, {
569
- locale,
460
+ // v9: Compute structured reply surfaces
461
+ const derivedReplyEnvelope = reflectiveTurn.replyEnvelope;
462
+ const replyEnvelope = {
463
+ subjectivityKernel: derivedReplyEnvelope.subjectivityKernel,
464
+ responseContract: derivedReplyEnvelope.responseContract,
465
+ generationControls: derivedReplyEnvelope.generationControls,
466
+ };
467
+ const promptRenderInputs = {
570
468
  userText: text || undefined,
571
469
  algorithmStimulus: appliedStimulus,
572
- classificationConfidence: this.lastStimulusAssessment?.confidence,
573
470
  personalityIntensity: this.cfg.personalityIntensity,
574
- relationContext: relationalTurn.relationContext,
575
- });
576
- // P10: Append processing depth info to autonomic description when depth is low
577
- let autonomicDesc;
578
- if (autonomicResult.state !== "ventral-vagal") {
579
- autonomicDesc = autonomicResult.description;
580
- if (autonomicResult.processingDepth < 0.5) {
581
- const depthNote = locale === "en"
582
- ? " Reflective capacity reduced — intuitive reactions."
583
- : "反思能力降低——直觉反应中。";
584
- autonomicDesc += depthNote;
585
- }
586
- }
471
+ metacognitiveNote: reflectiveTurn.metacognitiveNote,
472
+ decisionContext: reflectiveTurn.decisionContext,
473
+ ethicsContext: reflectiveTurn.ethicsContext,
474
+ sharedIntentionalityContext: reflectiveTurn.sharedIntentionalityContext,
475
+ experientialNarrative: reflectiveTurn.experientialNarrative,
476
+ autonomicDescription: reflectiveTurn.autonomicDescription,
477
+ autonomicState: reflectiveTurn.autonomicState,
478
+ primarySystemsDescription: reflectiveTurn.primarySystemsDescription,
479
+ subjectivityContext: derivedReplyEnvelope.subjectivityContext,
480
+ responseContractContext: derivedReplyEnvelope.responseContractContext,
481
+ policyContext: derivedReplyEnvelope.policyContext || undefined,
482
+ };
587
483
  if (this.cfg.compactMode) {
484
+ const externalContinuity = buildExternalContinuityEnvelope(throngletsExports);
588
485
  return {
589
486
  systemContext: "",
590
- dynamicContext: buildCompactContext(state, opts?.userId, {
591
- userText: text || undefined,
592
- algorithmStimulus: appliedStimulus,
593
- personalityIntensity: this.cfg.personalityIntensity,
594
- metacognitiveNote: metacogNote || undefined,
595
- decisionContext: decisionCtx || undefined,
596
- ethicsContext: ethicsCtx || undefined,
597
- sharedIntentionalityContext: sharedCtx || undefined,
598
- experientialNarrative: experientialNarrative,
599
- autonomicDescription: autonomicDesc,
600
- autonomicState: autonomicResult.state,
601
- primarySystemsDescription: primarySystemsDescription || undefined,
602
- subjectivityContext: replyEnvelope.subjectivityContext,
603
- responseContractContext: replyEnvelope.responseContractContext,
604
- policyContext: replyEnvelope.policyContext || undefined,
605
- }),
487
+ dynamicContext: buildCompactContext(state, opts?.userId, promptRenderInputs),
606
488
  stimulus: appliedStimulus,
607
489
  stimulusConfidence: this.lastStimulusAssessment?.confidence,
608
- policyModifiers: replyEnvelope.policyModifiers,
490
+ replyEnvelope,
491
+ policyModifiers: derivedReplyEnvelope.policyModifiers,
609
492
  subjectivityKernel: replyEnvelope.subjectivityKernel,
610
493
  responseContract: replyEnvelope.responseContract,
611
494
  generationControls: replyEnvelope.generationControls,
612
495
  sessionBridge,
613
496
  writebackFeedback,
614
- policyContext: replyEnvelope.policyContext,
497
+ externalContinuity,
498
+ throngletsExports,
499
+ policyContext: derivedReplyEnvelope.policyContext,
615
500
  };
616
501
  }
502
+ const externalContinuity = buildExternalContinuityEnvelope(throngletsExports);
617
503
  return {
618
504
  systemContext: this.getProtocol(locale),
619
- dynamicContext: buildDynamicContext(state, opts?.userId, {
620
- metacognitiveNote: metacogNote || undefined,
621
- decisionContext: decisionCtx || undefined,
622
- ethicsContext: ethicsCtx || undefined,
623
- sharedIntentionalityContext: sharedCtx || undefined,
624
- experientialNarrative: experientialNarrative,
625
- autonomicDescription: autonomicDesc,
626
- autonomicState: autonomicResult.state,
627
- primarySystemsDescription: primarySystemsDescription || undefined,
628
- policyContext: replyEnvelope.policyContext || undefined,
629
- }),
505
+ dynamicContext: buildDynamicContext(state, opts?.userId, promptRenderInputs),
630
506
  stimulus: appliedStimulus,
631
507
  stimulusConfidence: this.lastStimulusAssessment?.confidence,
632
- policyModifiers: replyEnvelope.policyModifiers,
508
+ replyEnvelope,
509
+ policyModifiers: derivedReplyEnvelope.policyModifiers,
633
510
  subjectivityKernel: replyEnvelope.subjectivityKernel,
634
511
  responseContract: replyEnvelope.responseContract,
635
512
  generationControls: replyEnvelope.generationControls,
636
513
  sessionBridge,
637
514
  writebackFeedback,
638
- policyContext: replyEnvelope.policyContext,
515
+ externalContinuity,
516
+ throngletsExports,
517
+ policyContext: derivedReplyEnvelope.policyContext,
639
518
  };
640
519
  }
641
520
  /**
@@ -0,0 +1,4 @@
1
+ import type { ExternalContinuityEnvelope, ThrongletsExport } from "./types.js";
2
+ export declare const EXTERNAL_CONTINUITY_SIGNAL_KINDS: readonly ["relation-milestone", "writeback-calibration"];
3
+ export declare const EXTERNAL_CONTINUITY_TRACE_KINDS: readonly ["continuity-anchor", "open-loop-anchor"];
4
+ export declare function buildExternalContinuityEnvelope(events: ThrongletsExport[]): ExternalContinuityEnvelope<ThrongletsExport>;
@@ -0,0 +1,21 @@
1
+ export const EXTERNAL_CONTINUITY_SIGNAL_KINDS = [
2
+ "relation-milestone",
3
+ "writeback-calibration",
4
+ ];
5
+ export const EXTERNAL_CONTINUITY_TRACE_KINDS = [
6
+ "continuity-anchor",
7
+ "open-loop-anchor",
8
+ ];
9
+ export function buildExternalContinuityEnvelope(events) {
10
+ const exports = [...events];
11
+ const signals = exports.filter((event) => event.primitive === "signal");
12
+ const traces = exports.filter((event) => event.primitive === "trace");
13
+ return {
14
+ provider: "thronglets",
15
+ mode: "optional",
16
+ version: 1,
17
+ exports,
18
+ signals,
19
+ traces,
20
+ };
21
+ }
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, SessionBridgeState, WritebackSignalType, WritebackSignalWeightMap, PendingWritebackCalibration, WritebackCalibrationFeedback, WritebackCalibrationMetric, 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, ThrongletsExportSubject, ThrongletsExportPrimitive, ThrongletsExportBase, RelationMilestoneExport, OpenLoopAnchorExport, WritebackCalibrationExport, ContinuityAnchorExport, ThrongletsExport, ThrongletsExportState, ExternalContinuityEvent, ExternalContinuityEnvelope, ThrongletsTraceTaxonomy, ThrongletsExternalContinuityRecord, ThrongletsTracePayload, ThrongletsTraceSerializationOptions, 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";
@@ -26,8 +26,13 @@ export type { DecisionBiasVector, AttentionWeights } from "./decision-bias.js";
26
26
  export { computeSubjectivityKernel, buildSubjectivityContext } from "./subjectivity.js";
27
27
  export { computeResponseContract, buildResponseContractContext } from "./response-contract.js";
28
28
  export { deriveGenerationControls } from "./host-controls.js";
29
+ export { deriveReplyEnvelope } from "./reply-envelope.js";
30
+ export type { ReplyEnvelope } from "./reply-envelope.js";
29
31
  export { computeAppraisalAxes, mergeAppraisalResidue, getResidueIntensity } from "./appraisal.js";
30
32
  export { computeRelationMove, evolveDyadicField, evolvePendingRelationSignals, getLoopPressure, applySessionBridge, applyWritebackSignals, createWritebackCalibrations, evaluateWritebackCalibrations, } from "./relation-dynamics.js";
33
+ export { EXTERNAL_CONTINUITY_SIGNAL_KINDS, EXTERNAL_CONTINUITY_TRACE_KINDS, buildExternalContinuityEnvelope, } from "./external-continuity.js";
34
+ export { deriveThrongletsExports } from "./thronglets-export.js";
35
+ export { taxonomyForThrongletsExport, serializeThrongletsExportAsTrace, serializeExternalContinuityForThronglets, } from "./thronglets-runtime.js";
31
36
  export { computeExperientialField, computeCoherence, detectUnnamedEmotion, computeAffectCore } from "./experiential-field.js";
32
37
  export type { ExperientialField, ExperientialQuality, ConstructionContext } from "./experiential-field.js";
33
38
  export { computeGenerativeSelf, predictSelfReaction, detectInternalConflicts, buildIdentityNarrative } from "./generative-self.js";
package/dist/index.js CHANGED
@@ -37,8 +37,12 @@ export { computeDecisionBias, computeAttentionWeights, computeExploreExploit, bu
37
37
  export { computeSubjectivityKernel, buildSubjectivityContext } from "./subjectivity.js";
38
38
  export { computeResponseContract, buildResponseContractContext } from "./response-contract.js";
39
39
  export { deriveGenerationControls } from "./host-controls.js";
40
+ export { deriveReplyEnvelope } from "./reply-envelope.js";
40
41
  export { computeAppraisalAxes, mergeAppraisalResidue, getResidueIntensity } from "./appraisal.js";
41
42
  export { computeRelationMove, evolveDyadicField, evolvePendingRelationSignals, getLoopPressure, applySessionBridge, applyWritebackSignals, createWritebackCalibrations, evaluateWritebackCalibrations, } from "./relation-dynamics.js";
43
+ export { EXTERNAL_CONTINUITY_SIGNAL_KINDS, EXTERNAL_CONTINUITY_TRACE_KINDS, buildExternalContinuityEnvelope, } from "./external-continuity.js";
44
+ export { deriveThrongletsExports } from "./thronglets-export.js";
45
+ export { taxonomyForThrongletsExport, serializeThrongletsExportAsTrace, serializeExternalContinuityForThronglets, } from "./thronglets-runtime.js";
42
46
  // Experiential field (P6 + P8 Barrett construction)
43
47
  export { computeExperientialField, computeCoherence, detectUnnamedEmotion, computeAffectCore } from "./experiential-field.js";
44
48
  // Generative self (P6)