@rain13sad/dsh-mnemo-affect 0.0.0-stage → 0.2.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.
@@ -0,0 +1,216 @@
1
+ /**
2
+ * @rain13sad/dsh-mnemo-affect —— 情感内核(§11 / §14.2 / §15)
3
+ *
4
+ * 四段管线:interocept → core affect → appraisal×context → label(仅渲染时)
5
+ * 对应 Barrett 四步:身体变化 → 感知 → 结合经验解释 → 情绪出现。
6
+ *
7
+ * 边界(代码注释与对外表述都要守住):
8
+ * · 这满足"有需要维持的内部状态",**不满足**"有主观体验"
9
+ * · `report()` 返回数值,不返回感受
10
+ * · 任何"我感到…"的措辞都不在此产生
11
+ */
12
+ import { Service, type Context } from '@deepseek-ai/cordis';
13
+ import z from '@deepseek-ai/schemastery';
14
+ import type { Appraisal, Intero, Pad, RelationalSnapshot } from '@rain13sad/dsh-mnemo-core';
15
+ import { type AffectCoefficients } from './appraisal.js';
16
+ import { derivePolicy, type InteroSignals } from './policy.js';
17
+ import { type PersonaState, type SchemaPattern } from './persist.js';
18
+ export declare const name = "mnemo-affect";
19
+ export declare const inject: string[];
20
+ export interface Config {
21
+ moodTau: number;
22
+ personaDriftEpsilon: number;
23
+ negativeWeight: number;
24
+ enabled: boolean;
25
+ coeff: AffectCoefficients;
26
+ }
27
+ export declare const Config: z<Config>;
28
+ export interface TurnInput {
29
+ text: string;
30
+ turn: number;
31
+ topic?: string;
32
+ goalEntities?: string[];
33
+ seenTopics?: Set<string>;
34
+ lastAssistantRejected?: boolean;
35
+ repeated?: boolean;
36
+ promise?: 'kept' | 'broken';
37
+ signals?: InteroSignals;
38
+ }
39
+ export interface TurnOutput {
40
+ appraisal: Appraisal;
41
+ pad: Pad;
42
+ mood: Pad;
43
+ relational: RelationalSnapshot;
44
+ policy: ReturnType<typeof derivePolicy>;
45
+ intero: Intero;
46
+ label: string;
47
+ }
48
+ export declare class AffectService extends Service {
49
+ config: Config;
50
+ private intero;
51
+ private pad;
52
+ private mood;
53
+ private relational;
54
+ private persona;
55
+ private persona0;
56
+ private lastTurn;
57
+ /** 人格版本链(§11.8 可回滚) */
58
+ private personaRev;
59
+ private personaHistory;
60
+ /** 离线环的原始样本:每轮的 PAD / 张力 / 是否被纠正 */
61
+ private history;
62
+ private lastPersistTurn;
63
+ private lastSchemaTurn;
64
+ private lastSchema;
65
+ private seenTopics;
66
+ /** 情绪事件(一次显著的起伏),带衰减;供面板画轨迹、供主动聊天挑话题 */
67
+ private episodes;
68
+ /** PAD 轨迹(每轮一个点,上限 240,够画 40 分钟的连续情绪) */
69
+ private trajectory;
70
+ /** 有情绪波动的轮数,用于依恋度 */
71
+ private emotionalTurns;
72
+ private negativeAccum;
73
+ private repeats;
74
+ constructor(ctx: Context, config: Config);
75
+ /** 当前情绪(本轮),供 recall 做门控与打分。 */
76
+ current(): Pad;
77
+ currentMood(): Pad;
78
+ currentIntero(): Intero;
79
+ relationalSnapshot(): RelationalSnapshot;
80
+ /** 六变量可手动注入(调试用,`/mnemo affect set`)。 */
81
+ setIntero(patch: Partial<Intero>): Intero;
82
+ /** 一轮的完整评价(快环)。 */
83
+ observe(input: TurnInput): TurnOutput;
84
+ /** 人格快照(面板与命令用)。 */
85
+ personaState(): PersonaState & {
86
+ baseline: number[];
87
+ history: Array<{
88
+ rev: number;
89
+ vector: number[];
90
+ }>;
91
+ };
92
+ /** 人格回滚(§11.8):回滚也算一次新版本,不做原地改写。 */
93
+ rollbackPersona(rev: number): {
94
+ ok: boolean;
95
+ message: string;
96
+ };
97
+ /**
98
+ * 依恋度(0..1):熟悉度 40% + 信任 30% + 共同情绪事件 30%。
99
+ * 刻意不包含"轮数"——刷轮数涨上来的不是依恋,是时长。
100
+ */
101
+ attachment(): number;
102
+ /** 关系阶段:陌生 → 熟悉 → 亲密 → 依赖(阈值与面板文案绑定,改要一起改) */
103
+ stage(): {
104
+ key: 'stranger' | 'familiar' | 'close' | 'attached';
105
+ label: string;
106
+ progress: number;
107
+ };
108
+ /** 情绪轨迹(面板画折线用) */
109
+ trajectorySeries(): Array<{
110
+ turn: number;
111
+ v: number;
112
+ a: number;
113
+ d: number;
114
+ }>;
115
+ /** 未平复的情绪事件(峰值 × 半衰),供主动聊天判断"他还在气头上吗" */
116
+ activeEpisodes(now?: number): Array<{
117
+ turn: number;
118
+ v: number;
119
+ a: number;
120
+ strength: number;
121
+ trigger: string;
122
+ }>;
123
+ /**
124
+ * 情感再评估(reappraisal):用**当前心境**重估一条记忆的效价。
125
+ * 记忆是建构性的——同一件事,心情好的时候想起来没那么糟。
126
+ * 只调 valence(情感维度),不动内容、不动 support(证据数不是情绪)。
127
+ */
128
+ reappraise(cellId: string): {
129
+ ok: boolean;
130
+ before: number;
131
+ after: number;
132
+ message: string;
133
+ };
134
+ /** 当前用户图式(离线环产物)。 */
135
+ schema(): SchemaPattern[];
136
+ /** 慢环落盘:关系模型 + 人格锚。失败不影响情感计算。 */
137
+ persist(): void;
138
+ /** 离线环:抽图式并写 kind=3 cell。 */
139
+ refreshSchema(): SchemaPattern[];
140
+ /** 热重载 / 重启后从库恢复(§14.7 可重建内存缓存)。 */
141
+ restoreFromMemory(): boolean;
142
+ policy(): TurnOutput['policy'];
143
+ /** affect_report 的数据源:**只有数值**,没有感受。 */
144
+ report(): Record<string, number | string>;
145
+ /** 面板需要、但不属于"本轮评价结果"的部分。 */
146
+ snapshotExtras(): {
147
+ persona: {
148
+ rev: number;
149
+ vector: number[];
150
+ baseline: number[];
151
+ };
152
+ schema: SchemaPattern[];
153
+ attachment: number;
154
+ stage: {
155
+ key: string;
156
+ label: string;
157
+ progress: number;
158
+ };
159
+ trajectory: Array<{
160
+ turn: number;
161
+ v: number;
162
+ a: number;
163
+ d: number;
164
+ }>;
165
+ episodes: Array<{
166
+ turn: number;
167
+ v: number;
168
+ a: number;
169
+ strength: number;
170
+ trigger: string;
171
+ }>;
172
+ };
173
+ /** 供面板消费的快照。 */
174
+ snapshot(): {
175
+ persona: {
176
+ rev: number;
177
+ vector: number[];
178
+ baseline: number[];
179
+ };
180
+ schema: SchemaPattern[];
181
+ attachment: number;
182
+ stage: {
183
+ key: string;
184
+ label: string;
185
+ progress: number;
186
+ };
187
+ trajectory: Array<{
188
+ turn: number;
189
+ v: number;
190
+ a: number;
191
+ d: number;
192
+ }>;
193
+ episodes: Array<{
194
+ turn: number;
195
+ v: number;
196
+ a: number;
197
+ strength: number;
198
+ trigger: string;
199
+ }>;
200
+ enabled: boolean;
201
+ intero: Intero;
202
+ pad: Pad;
203
+ mood: Pad;
204
+ relational: RelationalSnapshot;
205
+ policy: import("@rain13sad/dsh-mnemo-core").AffectPolicy;
206
+ };
207
+ last(): TurnOutput | null;
208
+ /** 恢复(热重载后从 kind=5 / kind=4 cell 重建,§14.7 可重建内存缓存)。 */
209
+ restore(rel: Partial<RelationalSnapshot>, mood?: Pad): void;
210
+ }
211
+ export declare function apply(ctx: Context, config: Config): AffectService;
212
+ export { appraise, coreAffect, integrateMood, label, clampPersona } from './appraisal.js';
213
+ export { deriveUserSchema, readPersisted, relationalCell, personaCell, schemaCell } from './persist.js';
214
+ export type { PersonaState, SchemaPattern } from './persist.js';
215
+ export { derivePolicy, interocept } from './policy.js';
216
+ export { updateRelational, personaFromAttunement, initialRelational } from './relational.js';
@@ -0,0 +1,52 @@
1
+ /**
2
+ * 情感状态的持久化与离线抽象(对应 §11.5 / §11.7 / §11.8)
3
+ *
4
+ * 三个环路里,只有"快环"是纯内存的:
5
+ * 快环(每轮) → 本轮 PAD 与策略,写 affect/appraisal 事件
6
+ * 慢环(每会话)→ mood / 关系模型 / persona,**必须落盘**,否则重启就忘
7
+ * 离线环(每 N 轮)→ 用户 schema(kind=3),"这个人是什么样"
8
+ *
9
+ * 落盘方式是"用记忆库自己的格式"而不是另建一张表:
10
+ * kind=5 关系模型 → 一条 cell(flags.bit1 不衰减)
11
+ * kind=4 人格锚 → 一条 cell(不可合并、不可衰减)
12
+ * kind=3 用户图式 → 由离线环产出,可被后续 pass 继续合并
13
+ *
14
+ * 这样做的好处是"热重载可重建"(§14.7):情感服务挂了重启,从这三类 cell 读回来即可,
15
+ * 不需要额外的状态存储,也不需要和主库做一致性维护。
16
+ */
17
+ import { type MemCell, type MemoryService, type Pad, type RelationalSnapshot } from '@rain13sad/dsh-mnemo-core';
18
+ export interface PersonaState {
19
+ vector: number[];
20
+ rev: number;
21
+ }
22
+ /** 关系模型 → 一条 kind=5 cell。槽位承载数值,digest 只写摘要(不进 MRS 正文)。 */
23
+ export declare function relationalCell(memory: MemoryService, rel: RelationalSnapshot, persona: PersonaState, now: number): MemCell;
24
+ /** 人格锚 → kind=4 cell,flags.bit1(不可衰减),不参与合并。 */
25
+ export declare function personaCell(memory: MemoryService, persona: PersonaState, now: number): MemCell;
26
+ export interface SchemaPattern {
27
+ topic: string;
28
+ pattern: string;
29
+ confidence: number;
30
+ support: number;
31
+ }
32
+ /**
33
+ * 离线环:把散落在几十轮里的情感反应,抽象成一条关于"这个人"的图式。
34
+ * 这是整套系统里唯一真正的"学习"——它反过来成为下次评价的先验。
35
+ *
36
+ * 判据刻意保守:样本 < 3 不产结论,置信度按样本量折算。
37
+ * 宁可第一次猜不准,也不要拿一条 3 个样本的"规律"去改变行为。
38
+ */
39
+ export declare function deriveUserSchema(history: Array<{
40
+ turn: number;
41
+ topic: string;
42
+ pad: Pad;
43
+ strain: number;
44
+ corrected: boolean;
45
+ }>, minSamples?: number): SchemaPattern[];
46
+ /** 图式 → kind=3 cell(可被后续 NREM pass 继续合并)。 */
47
+ export declare function schemaCell(memory: MemoryService, p: SchemaPattern, now: number): MemCell;
48
+ /** 从库里读回最近一条关系模型 / 人格锚(热重载与重启后的恢复路径)。 */
49
+ export declare function readPersisted(memory: MemoryService): {
50
+ relational?: RelationalSnapshot;
51
+ persona?: PersonaState;
52
+ };
@@ -0,0 +1,47 @@
1
+ /**
2
+ * 情感 → 行为:策略表(对应 §11.6,硬约束)
3
+ *
4
+ * 情感若不影响行为,就只是装饰。以下映射**强制**,且可回归测试(test/policy.test.mjs)。
5
+ * 每一条都返回 `reasons`,让"为什么这轮更谨慎"变成可指认的事实,而不是玄学。
6
+ *
7
+ * 谄媚的三道刹车(§19.4)在这里落地:
8
+ * · warmth 只作用于 verbosity/hedging,不作用于 content
9
+ * · trust 高不降低异议意愿,只降低确认频次
10
+ * · strain 只由"重复追问/明确不满"驱动,不由"用户不同意"驱动
11
+ */
12
+ import type { AffectPolicy, Intero, Pad, RelationalSnapshot } from '@rain13sad/dsh-mnemo-core';
13
+ export interface PolicyInput {
14
+ pad: Pad;
15
+ mood: Pad;
16
+ intero: Intero;
17
+ relational: RelationalSnapshot;
18
+ /** 当前会话轮次,用于 progress 相关规则 */
19
+ turns: number;
20
+ /** 本会话是否已有 goal;无 goal 时 progress 规则不适用 */
21
+ hasGoal?: boolean;
22
+ }
23
+ export declare function derivePolicy(input: PolicyInput): AffectPolicy;
24
+ /** 从运行时信号推导 6 个内感受变量(§11.1)。全部是真实可测量,不是修辞。 */
25
+ export interface InteroSignals {
26
+ /** 活跃 job 数 */
27
+ activeJobs?: number;
28
+ /** 上下文 token 占比 [0,1] */
29
+ contextRatio?: number;
30
+ /** 近 N 轮召回平均分 [0,1] */
31
+ recallMean?: number;
32
+ /** 工具错误率 [0,1] */
33
+ toolErrorRate?: number;
34
+ /** CONTRADICTS 边密度 [0,1] */
35
+ conflictDensity?: number;
36
+ /** 负向评价累积 [0,1] */
37
+ negativeAccum?: number;
38
+ /** 重复提问率 [0,1] */
39
+ repeatRate?: number;
40
+ /** goal 进度 [0,1](无 goal 时 undefined) */
41
+ progress?: number;
42
+ /** 预算余量 [0,1] */
43
+ budget?: number;
44
+ /** 距离上次进度更新的轮数 */
45
+ roundsSinceProgress?: number;
46
+ }
47
+ export declare function interocept(s: InteroSignals, prev?: Intero): Intero;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * 关系模型(对应 §11.5,修 D-12)
3
+ *
4
+ * 三条关键设计,缺一条就会退化成"越聊越谄媚":
5
+ * 1. 不对称更新:负面权重是正面的 3 倍(信任建立慢、崩塌快)
6
+ * 2. boundaries 只增不减:用户划的边界不能被"后来聊得好"自动撤销
7
+ * 3. attunement 驱动 persona 微调:高 → 更简洁;低 → 更多澄清
8
+ *
9
+ * attunement 的事件来源必须是**可检测的**。v0.1 假设存在 affirmed/corrected 事件
10
+ * 却没定义谁产生——这里用三条启发式,各自带置信度,低置信不更新。
11
+ */
12
+ import type { RelationalSnapshot } from '@rain13sad/dsh-mnemo-core';
13
+ export interface RelationalModel extends RelationalSnapshot {
14
+ /** 内部:上次 attunement 更新的轮次,避免同一轮重复计分 */
15
+ lastAttuneTurn: number;
16
+ }
17
+ export declare function initialRelational(): RelationalModel;
18
+ export interface RelationalUpdate {
19
+ model: RelationalModel;
20
+ delta: {
21
+ trust: number;
22
+ attunement: number;
23
+ repairDebt: number;
24
+ };
25
+ reason: string[];
26
+ }
27
+ export interface UpdateOptions {
28
+ text: string;
29
+ turn: number;
30
+ /** 用户是否重复了同一请求(明确纠正的强信号) */
31
+ repeated?: boolean;
32
+ /** 承诺兑现(kept)或违背(broken),来自工具执行结果 */
33
+ promise?: 'kept' | 'broken';
34
+ /** 负面权重(默认 3,§11.5) */
35
+ negativeWeight?: number;
36
+ /** trust 学习率 η */
37
+ eta?: number;
38
+ }
39
+ export declare function updateRelational(model: RelationalModel, opts: UpdateOptions): RelationalUpdate;
40
+ /**
41
+ * attunement → persona 微调(§11.5 第 3 条)。
42
+ * 高 → 更简洁少解释;低 → 更多澄清与铺垫。返回的是**策略参数**,不是人设文案。
43
+ */
44
+ export declare function personaFromAttunement(attunement: number): {
45
+ verbosity: -1 | 0 | 1;
46
+ clarification: number;
47
+ hedging: number;
48
+ };
package/package.json CHANGED
@@ -1,6 +1,61 @@
1
1
  {
2
2
  "name": "@rain13sad/dsh-mnemo-affect",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.0",
4
+ "description": "情感内核:内感受 / 评价 / PAD / 心境 / 关系模型(ctx.affect)",
5
+ "keywords": [
6
+ "dsh",
7
+ "deepseek-harness",
8
+ "cordis",
9
+ "agent-memory",
10
+ "typescript",
11
+ "affect",
12
+ "emotion",
13
+ "appraisal",
14
+ "pad-model"
15
+ ],
16
+ "homepage": "https://github.com/Rain13Sad/bcf-mnemovault#readme",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/Rain13Sad/bcf-mnemovault.git",
20
+ "directory": "packages/affect"
21
+ },
22
+ "bugs": {
23
+ "url": "https://github.com/Rain13Sad/bcf-mnemovault/issues"
24
+ },
25
+ "author": "Rain13Sad",
26
+ "license": "MIT",
27
+ "type": "module",
28
+ "main": "./lib/index.js",
29
+ "types": "./lib/types/index.d.ts",
30
+ "exports": {
31
+ ".": {
32
+ "types": "./lib/types/index.d.ts",
33
+ "default": "./lib/index.js"
34
+ },
35
+ "./package.json": "./package.json"
36
+ },
37
+ "files": [
38
+ "lib",
39
+ "cordis.patch.yml",
40
+ "README.md"
41
+ ],
42
+ "engines": {
43
+ "dsh": ">=0.2.1-rc.3 <0.3.0"
44
+ },
45
+ "dsh": {
46
+ "bundle": {
47
+ "patch": "./cordis.patch.yml"
48
+ }
49
+ },
50
+ "peerDependencies": {
51
+ "@deepseek-ai/cordis": "*",
52
+ "@deepseek-ai/dsh-session": "*"
53
+ },
54
+ "dependencies": {
55
+ "@deepseek-ai/schemastery": "^3.18.5",
56
+ "@rain13sad/dsh-mnemo-core": "^0.2.0"
57
+ },
58
+ "publishConfig": {
59
+ "access": "public"
60
+ }
61
+ }