@deepmaid/maid-emotion 0.0.0-stage → 0.1.0-alpha.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 kenyonxu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ - insert:
2
+ - id: deepmaid-maid-emotion
3
+ name: '@deepmaid/maid-emotion'
package/lib/index.d.ts ADDED
@@ -0,0 +1,240 @@
1
+ //#region src/state.d.ts
2
+ interface MoodState {
3
+ label: string;
4
+ intensity: number;
5
+ since: number;
6
+ cause?: string;
7
+ }
8
+ interface SignalState {
9
+ lastMessageAt: number;
10
+ lastMessageChars: number;
11
+ todayTurnCount: number;
12
+ todayDate: string;
13
+ lastMessageExcerpt?: string | undefined;
14
+ }
15
+ type EmotionTier = 'fast' | 'mid' | 'deep';
16
+ type EmotionTrend = 'rising' | 'stable' | 'falling';
17
+ interface EmotionDimensionState {
18
+ value: number;
19
+ trend: EmotionTrend;
20
+ tier: EmotionTier;
21
+ }
22
+ interface MasterMoodState {
23
+ label: string;
24
+ intensity: number;
25
+ since: number;
26
+ }
27
+ /** per-maid 情绪子树(M3a 规格 §4.1):跨会话延续;缺 = v1.x maid 或旧格式(读取时懒初始化) */
28
+ interface EmotionSubtree {
29
+ dimensions: Record<string, EmotionDimensionState>;
30
+ masterMood: MasterMoodState | null;
31
+ updatedAt: number;
32
+ }
33
+ interface HistoryEntry {
34
+ t: number;
35
+ vectors: Record<string, number>;
36
+ emotion?: Record<string, number> | undefined;
37
+ }
38
+ interface MaidEmotionState {
39
+ vectors: Record<string, number>;
40
+ prevVectors: Record<string, number>;
41
+ mood: MoodState | null;
42
+ signals: SignalState;
43
+ cumulativeTurns: number;
44
+ updatedAt: number;
45
+ history: HistoryEntry[];
46
+ emotion?: EmotionSubtree | undefined;
47
+ }
48
+ //#endregion
49
+ //#region src/drivers.d.ts
50
+ /** LLM judge 产物(providers/judge.ts 同型;强度档 0-3——LLM 打档比打分稳) */
51
+ interface EmotionJudgeResult {
52
+ praised: number;
53
+ deepTalk: number;
54
+ physicalIntimacy: number;
55
+ masterEmotion: {
56
+ label: string;
57
+ intensity: number;
58
+ explicit: boolean;
59
+ } | null;
60
+ }
61
+ //#endregion
62
+ //#region src/config.d.ts
63
+ /**
64
+ * emotion.yml 配置加载与校验(T5 正式类型落点)。
65
+ * 文件缺省 → undefined(女仆不带情绪配置是合法形态,零 warn);
66
+ * 坏文件(YAML 解析失败/非 mapping)→ warn 后 undefined;
67
+ * 坏行(单条维度/规则不合法)→ warn 跳过该条,其余照常(规格 §7)。
68
+ * yml 键用 snake_case(static_rules/time_slots/…),映射到消费面的 camelCase 字段。
69
+ */
70
+ /** mood 规则:pattern 为正则源(装载时编译校验),narrative 为情绪叙事句模板(T6 组装 moodNarrative 用) */
71
+ interface MoodRule {
72
+ event: string;
73
+ pattern: string;
74
+ mood: string;
75
+ intensity: number;
76
+ narrative?: string;
77
+ }
78
+ /** 单个表达向量维度(v1.x score_rules 四元组全量映射 + maxPerTurn/floor/ceiling 增强) */
79
+ interface DimensionConfig {
80
+ label: string;
81
+ keywords: string[];
82
+ score: number;
83
+ weight?: number;
84
+ missPenalty?: number;
85
+ maxPerTurn: number;
86
+ floor?: number;
87
+ ceiling?: number;
88
+ decayScale?: number;
89
+ }
90
+ //#endregion
91
+ //#region src/engine.d.ts
92
+ /** 一轮判定输入:仅主人原始输入(白名单过滤在 lifecycle,引擎结构性只见 userText) */
93
+ interface TurnInput {
94
+ userText: string;
95
+ at: number;
96
+ sessionId: string;
97
+ }
98
+ interface EmotionConfigLike {
99
+ dimensions: Record<string, DimensionConfig>;
100
+ turnStages?: Record<string, string[]>;
101
+ moodRules?: MoodRule[];
102
+ keywordRules?: {
103
+ pattern: string;
104
+ rules: string[];
105
+ }[];
106
+ }
107
+ /** 一轮判定产物:deltas 供 applyTurn 累加;moodEvent 供情绪状态机迁移 */
108
+ interface EngineResult {
109
+ vectorDeltas: Record<string, number>;
110
+ moodEvent: MoodRule | null;
111
+ turnStageKey: string | null;
112
+ }
113
+ declare function scoreTurn(vectors: Record<string, number>, input: TurnInput, cfg: EmotionConfigLike): EngineResult;
114
+ type ReunionTier = 'soft' | 'distant' | 'estranged';
115
+ //#endregion
116
+ //#region src/providers/judge.d.ts
117
+ /** 判定 provider 接缝(M3 LLM 判分同面插拔,不动 engine) */
118
+ interface JudgeProvider {
119
+ id: string;
120
+ score(vectors: Record<string, number>, input: TurnInput, cfg: EmotionConfigLike): ReturnType<typeof scoreTurn>;
121
+ }
122
+ /** 判分输入:本轮主人消息 + 前 N 条(窗口默认 2,可配 0-3;只装主人原始输入,白名单在 lifecycle) */
123
+ interface EmotionJudgeInput {
124
+ current: string;
125
+ previous: string[];
126
+ }
127
+ interface EmotionJudgeProvider {
128
+ id: string;
129
+ /** null = 本轮零内容事件(fail-open:abort/空路由/llm 不可用/解析失败,均已在内部 warn 消化) */
130
+ judge(input: EmotionJudgeInput, signal?: AbortSignal): Promise<EmotionJudgeResult | null>;
131
+ }
132
+ //#endregion
133
+ //#region src/state-store.d.ts
134
+ /**
135
+ * 状态存取缝(接口先行,M3a 规格 §2 拍板:状态底座并入 maid-emotion,存取抽接口;
136
+ * M4 world 状态需要共享时再提升独立 seam——届时消费方(lifecycle/service)零改动)。
137
+ */
138
+ interface StateStore {
139
+ load(maidId: string): MaidEmotionState | undefined;
140
+ save(maidId: string, state: MaidEmotionState): void;
141
+ }
142
+ //#endregion
143
+ //#region src/lifecycle.d.ts
144
+ declare module '@deepseek-ai/dsh-llm' {
145
+ interface MessageSourceMap {
146
+ 'plugin:maid-emotion': {
147
+ kind: 'plugin:maid-emotion';
148
+ };
149
+ }
150
+ }
151
+ /**
152
+ * maid-emotion 生命周期(T6 装配):turn/end 消费主人原始输入 → judge → 状态落盘;
153
+ * agent/pre-step 注入叙事投影(durable user 面 <system-reminder> 事件,缓存纪律铁律 3)。
154
+ * 钩子形态照 maid-memory lifecycle:agent/pre-step 运行时字符串派发(duck-typing),
155
+ * turn/end 经 session/event firehose(durable SessionEvent,非 cordis 钩子)。
156
+ */
157
+ interface MaidEmotionConfig {
158
+ stateFile: string;
159
+ presetRoots: string[];
160
+ allowMaids?: string[];
161
+ excludeSources?: string[];
162
+ weather?: {
163
+ location?: string;
164
+ lat?: number;
165
+ lon?: number;
166
+ detail?: 'brief' | 'full';
167
+ ttlMs?: number;
168
+ primary?: string;
169
+ fallback?: string;
170
+ };
171
+ projectionBudgetTokens?: number;
172
+ vectorHalfLifeMs?: number;
173
+ moodHalfLifeMs?: number;
174
+ trendBand?: number;
175
+ debug?: boolean;
176
+ timezone?: string;
177
+ /** 测试注入(照 maid-memory distiller 先例):缺省 rulesJudge(T4) */
178
+ judge?: JudgeProvider;
179
+ /** 情绪内容判分(测试注入缝);缺省:emotionJudgeRoute 建 llmJudge;均无 → 内容驱动停用(行为规则仍生效) */
180
+ emotionJudge?: EmotionJudgeProvider;
181
+ /** 生产副脑路由(M1b syncTurn 同款);模型可配,不必是主对话模型 */
182
+ emotionJudgeRoute?: {
183
+ provider: string;
184
+ model: string;
185
+ };
186
+ /** 状态存取缝(测试注入,照 config.judge 先例);缺省 createJsonFileStateStore(stateFile) */
187
+ store?: StateStore;
188
+ /** 时钟注入(测试用);缺省 Date.now() */
189
+ now?: () => number;
190
+ }
191
+ interface MaidEmotionService {
192
+ /** 可观测读:maidId → 对齐后的当前持久状态(只读快照,不触发衰减物化) */
193
+ stateOf(maidId: string): MaidEmotionState | undefined;
194
+ /**
195
+ * 统一活力入口(maid-gestures 前置,重逢回补管线同款):deltas 键过滤到 emotionVectors
196
+ * 声明集 → applyEmotionTurn(增益/trend 管线)→ 落盘。true=落账成功;false=maid 未注册 /
197
+ * preset 无情绪配置 / 过滤后空集 / 管线异常(warn)。tier 护栏在调用方——服务面只做管线,不管 tier。
198
+ */
199
+ applyDeltas(maidId: string, deltas: Record<string, number>): boolean;
200
+ /**
201
+ * 只读快照(M3c Task 3,maid-voice reflect 消费面):投影路径同款 load → align →
202
+ * applyDecay(now) 惰性组装,**绝不写 store**;未注册 maid / 无情绪配置 → undefined。
203
+ */
204
+ getSnapshot(maidId: string): EmotionSnapshot | undefined;
205
+ }
206
+ /**
207
+ * 情绪快照(M3c Task 3 规格 §4):跨 seam 只读投影视图。lastWeather 是进程内最近读数
208
+ * (重启即失,规格 §4.2 已知简化——不落盘);其余字段全部可从持久状态 + 配置组装。
209
+ */
210
+ interface EmotionSnapshot {
211
+ vector: Record<string, number>;
212
+ trends: Record<string, EmotionTrend> | undefined;
213
+ reunionTier: ReunionTier | null;
214
+ sinceLastMessageMs: number;
215
+ lastMasterMessage: {
216
+ at: number;
217
+ excerpt: string;
218
+ } | undefined;
219
+ lastWeather: {
220
+ at: number;
221
+ text: string;
222
+ } | undefined;
223
+ calendarSentences: string[];
224
+ timeText: string;
225
+ }
226
+ /**
227
+ * 会话来源(供 excludeSources 判定)。执行期核对(dsh 0.1.2-alpha.3):SessionHeader 字段集为
228
+ * version/id/createdAt/cwd/parentSession/seedLength/origin('subagent')/delegationDepth/agentPreset,
229
+ * **无 source/lane 字段**;cron 车道唯一稳定标识是 maid-cron 的 `cron_` sessionId 前缀
230
+ * (maid-cron engine.ts:108 `cron_${jobId}_${iso}`)——M1c cron-lane 快照同源判定路径。
231
+ */
232
+ declare function sessionSource(sessionId: string): string | undefined;
233
+ declare function alignStateToConfig(state: MaidEmotionState, dimensionIds: readonly string[], emotionTiers?: Record<string, EmotionTier>): MaidEmotionState;
234
+ //#endregion
235
+ //#region src/index.d.ts
236
+ declare const name = "maid-emotion";
237
+ declare const inject: string[];
238
+ declare const apply: (ctx: any, config: MaidEmotionConfig) => (() => Promise<void>);
239
+ //#endregion
240
+ export { type EmotionSnapshot, type MaidEmotionConfig, type MaidEmotionService, alignStateToConfig, apply, inject, name, sessionSource };