@deepmaid/maid-voice 0.0.0-stage → 0.1.0-alpha.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/LICENSE +21 -0
- package/cordis.patch.yml +3 -0
- package/lib/index.d.ts +350 -0
- package/lib/index.js +7581 -0
- package/package.json +42 -3
- package/README.md +0 -3
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.
|
package/cordis.patch.yml
ADDED
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
//#region src/pack.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* maid-voice pack.yml schema 解析(M3c Task 4,规格 §2.1-2.2):输入是 maid-identity
|
|
4
|
+
* `resolvePack` 的 raw mapping(读取层零 schema,校验归本层),产出规范化 VoicePack。
|
|
5
|
+
* 校验器风格照 maid-emotion config.ts——局部 isMapping/isNumber/isStringArray 助手、
|
|
6
|
+
* 坏条 warn 跳过其余照常、可选节坏 → warn 后整节弃(其余照常)、未知顶层键 warn 不静默。
|
|
7
|
+
*
|
|
8
|
+
* 严格度(brief 拍板):id/kind 必填(坏 → undefined + warn,整包不用);cases 逐条校验
|
|
9
|
+
* (id 非空、domain 四值枚举、when 各值区间二数值且 min<max、gate 四值枚举、lines 非空
|
|
10
|
+
* 字符串组),坏条 warn 跳过;重复 case id 后者 warn 跳过;schedule 坏 → warn 后整节弃;
|
|
11
|
+
* temperamentRaw 原样透传(形状校验归 maid-emotion parseTemperamentBase,Task 2 已落)。
|
|
12
|
+
*
|
|
13
|
+
* when 区间双形态(内部表示统一 WhenRange):
|
|
14
|
+
* - 字符串字面量 "[0, 20)"(半开)/ "[0, 100]"(闭)——yml 里须带引号:不带引号的 `[0, 20)`
|
|
15
|
+
* 是 yaml 层解析错误,在 resolvePackFile 即 warn 整包弃;
|
|
16
|
+
* - 原生数组 [0, 20](两数值)——无括号可辨,视为闭区间(maxInclusive: true)。
|
|
17
|
+
* min 恒含(yml 不设 "(a, b]" 形态);含/排除语义的数值断言由 Task 6 检索测试锁。
|
|
18
|
+
*/
|
|
19
|
+
/** 案例域(规格 §3.1):daily 日常 | wilted 蔫了 | reunion 重逢 | intimate 亲密(M4d 预留) */
|
|
20
|
+
type CaseDomain = 'daily' | 'wilted' | 'reunion' | 'intimate';
|
|
21
|
+
/** 四门象限(规格 §3.2,desire×inhibition):open | cautious | ajar(留门)| reserved */
|
|
22
|
+
type Gate = 'open' | 'cautious' | 'ajar' | 'reserved';
|
|
23
|
+
/** when 区间内部表示:min 恒含;maxInclusive 承载半开 [min,max) / 闭 [min,max] 语义(Task 6 检索消费) */
|
|
24
|
+
interface WhenRange {
|
|
25
|
+
min: number;
|
|
26
|
+
max: number;
|
|
27
|
+
maxInclusive: boolean;
|
|
28
|
+
}
|
|
29
|
+
/** 单条情景案例:domain × when 向量区间(缺省 = 全域空映射)× gate(可选)× 台词池 */
|
|
30
|
+
interface PackCase {
|
|
31
|
+
id: string;
|
|
32
|
+
domain: CaseDomain;
|
|
33
|
+
when: Record<string, WhenRange>;
|
|
34
|
+
gate?: Gate;
|
|
35
|
+
lines: string[];
|
|
36
|
+
}
|
|
37
|
+
/** 作息表夜间段(M4b 全日化复用同文件:pack schedule 节下还有 day 等节位,本层只认 night) */
|
|
38
|
+
interface PackSchedule {
|
|
39
|
+
sleep: string;
|
|
40
|
+
wake: string;
|
|
41
|
+
activities: string[];
|
|
42
|
+
}
|
|
43
|
+
/** 规范化性格包:persona(气质 + 作息 + 案例)/ flavor(仅案例,world 风味层) */
|
|
44
|
+
interface VoicePack {
|
|
45
|
+
id: string;
|
|
46
|
+
kind: 'persona' | 'flavor';
|
|
47
|
+
name?: string;
|
|
48
|
+
temperamentRaw?: unknown;
|
|
49
|
+
schedule?: PackSchedule;
|
|
50
|
+
cases: PackCase[];
|
|
51
|
+
}
|
|
52
|
+
type Warn$1 = (message: string) => void;
|
|
53
|
+
/** schedule 节解析(包内跨文件共用,library.ts overlay 同款原料):只认 night 子节
|
|
54
|
+
* (M4b 全日化的其余节位本层不枚举不 warn);坏 → 整节弃(其余照常)。 */
|
|
55
|
+
declare function parseSchedule(node: unknown, where: string, warn: Warn$1): PackSchedule | undefined;
|
|
56
|
+
/** cases 列表节解析(包内跨文件共用,library.ts overlay 同款原料):缺省空列表(零 warn)、
|
|
57
|
+
* 非列表 warn 后空、坏条 warn 跳过其余照常、重复 case id 后者 warn 跳过。 */
|
|
58
|
+
declare function parseCases(node: unknown, where: string, warn: Warn$1): PackCase[];
|
|
59
|
+
/**
|
|
60
|
+
* pack.yml 规范化入口:raw 为 resolvePack 的 yaml parse 产物(缺省 undefined = 包不存在,
|
|
61
|
+
* 合法形态零 warn)。id/kind 必填坏 → 整包 undefined;其余按「坏条跳过/坏节弃」容错。
|
|
62
|
+
*/
|
|
63
|
+
declare function parseVoicePack(raw: Record<string, unknown> | undefined, where: string, warn: Warn$1): VoicePack | undefined;
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/library.d.ts
|
|
66
|
+
/** 三层合并后的女仆案例库(检索层 Task 6 消费;schedule 缺省 undefined = 无作息可注) */
|
|
67
|
+
interface VoiceLibrary {
|
|
68
|
+
cases: PackCase[];
|
|
69
|
+
schedule: PackSchedule | undefined;
|
|
70
|
+
}
|
|
71
|
+
type Warn = (message: string) => void;
|
|
72
|
+
/** overlay 解析产物:与 pack 同款原料,仅 cases/schedule 两节有效 */
|
|
73
|
+
interface OverlayContent {
|
|
74
|
+
cases: PackCase[];
|
|
75
|
+
schedule?: PackSchedule;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* voice-overlay.yml 解析入口(与 pack 不同:id/kind 缺省容错,仅 cases/schedule 有效)。
|
|
79
|
+
* raw 为调用方装载的 yaml parse 产物;缺省 undefined(文件不存在是合法形态,零 warn)。
|
|
80
|
+
* cases 规则与 parseVoicePack 完全同款(坏条跳过、重复 id 后者跳过)。
|
|
81
|
+
*/
|
|
82
|
+
declare function parseOverlay(raw: Record<string, unknown> | undefined, where: string, warn: Warn): OverlayContent | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* 三层继承解析(规格 §2.3):persona 模板(voice.pack)← flavor 风味(voice.worldFlavor)
|
|
85
|
+
* ← per-maid overlay(voice-overlay.yml 解析产物)。同 case id 整条覆盖、新 id 追加;
|
|
86
|
+
* 层缺失/解析失败跳过不阻断。无任何层 → 空库(fail-open,后续注入静默)。
|
|
87
|
+
*/
|
|
88
|
+
declare function resolveVoiceLibrary(input: {
|
|
89
|
+
resolvePack: ((packId: string) => Record<string, unknown> | undefined) | undefined;
|
|
90
|
+
voice: {
|
|
91
|
+
pack?: string;
|
|
92
|
+
worldFlavor?: string;
|
|
93
|
+
} | undefined;
|
|
94
|
+
overlayRaw: Record<string, unknown> | undefined;
|
|
95
|
+
scheduleRaw: Record<string, unknown> | undefined;
|
|
96
|
+
warn: (m: string) => void;
|
|
97
|
+
}): VoiceLibrary;
|
|
98
|
+
//#endregion
|
|
99
|
+
//#region src/retrieval.d.ts
|
|
100
|
+
/** 四门象限(desire×inhibition,中点默认 50 由调用方传):open 高desire低inhibition /
|
|
101
|
+
* cautious 双低 / ajar 双高 / reserved 低desire高inhibition;恰在中点归高;任一维缺失 → undefined。 */
|
|
102
|
+
declare function gateOf(vector: Record<string, number>, midpoint: number): Gate | undefined;
|
|
103
|
+
/** 情景推导(规格 §3.1 规则化,参数由调用方传):wilted = energy < wiltedThreshold(严格
|
|
104
|
+
* 小于,energy=20 阈值 20 不蔫);energy 缺失/不蔫均归缺省域 daily。reunion 优先规则与
|
|
105
|
+
* intimate(M4d 预留)不进本函数,由调用方推导后直接喂 selectCases。 */
|
|
106
|
+
declare function domainOf(vector: Record<string, number>, opts: {
|
|
107
|
+
wiltedThreshold: number;
|
|
108
|
+
}): Exclude<CaseDomain, 'reunion' | 'intimate'>;
|
|
109
|
+
/**
|
|
110
|
+
* 选片确定序(规格 §3.2):domain 匹配 → when 区间覆盖当前向量(缺省空 when 全域)→
|
|
111
|
+
* gate 匹配优先 → id 字典序 tie-break(码位序,跨环境确定);取 caseGroupMax 条。
|
|
112
|
+
* 空域返回 [](不注入不报错);输入数组不改序(filter 副本上排序,library.cases 复用安全)。
|
|
113
|
+
*/
|
|
114
|
+
declare function selectCases(cases: readonly PackCase[], domain: CaseDomain, vector: Record<string, number>, gate: Gate | undefined, caseGroupMax: number): PackCase[];
|
|
115
|
+
/**
|
|
116
|
+
* 每轮轻校验(纯函数,零模型):active 缺失 → false(首轮必选);domain 变 → false;
|
|
117
|
+
* caseIds 里每条仍存在(层重载消失即 false)且其 when 区间仍覆盖当前向量 → true。
|
|
118
|
+
* gate 迁移不触发跃迁(拍板):gate 不参与校验、仅影响下次重选——防中点附近抖动换组;
|
|
119
|
+
* 尾参 `_gate` 只为调用车道对称,void 引用照 maid-delivery 先例(eslint 不认 `_` 前缀尾参)。
|
|
120
|
+
*/
|
|
121
|
+
declare function groupStillMatches(active: {
|
|
122
|
+
domain: CaseDomain;
|
|
123
|
+
caseIds: string[];
|
|
124
|
+
} | undefined, cases: readonly PackCase[], domain: CaseDomain, vector: Record<string, number>, _gate: Gate | undefined): boolean;
|
|
125
|
+
//#endregion
|
|
126
|
+
//#region src/state.d.ts
|
|
127
|
+
/** 跨轮 voice 状态(per-maid,文件摆放归 lifecycle):active = 当前生效案例组,缺 = 首轮前 */
|
|
128
|
+
interface VoiceState {
|
|
129
|
+
active?: {
|
|
130
|
+
domain: CaseDomain;
|
|
131
|
+
caseIds: string[];
|
|
132
|
+
since: number;
|
|
133
|
+
} | undefined;
|
|
134
|
+
overnightConsumedDate?: string | undefined;
|
|
135
|
+
}
|
|
136
|
+
declare function loadVoiceState(file: string): VoiceState;
|
|
137
|
+
declare function saveVoiceState(file: string, state: VoiceState): void;
|
|
138
|
+
declare function dateKeyIn(ms: number, timezone: string): string;
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region src/decide.d.ts
|
|
141
|
+
/** 单轮跃迁决策:none = 状态未变零注入;inject = 跃迁重选(caseIds 可空 = 空域,记 active 不注入) */
|
|
142
|
+
interface TurnDecision {
|
|
143
|
+
action: 'none' | 'inject';
|
|
144
|
+
caseIds: string[];
|
|
145
|
+
domain: CaseDomain;
|
|
146
|
+
}
|
|
147
|
+
declare function decideTurn(input: {
|
|
148
|
+
state: VoiceState;
|
|
149
|
+
cases: readonly PackCase[];
|
|
150
|
+
domain: CaseDomain;
|
|
151
|
+
vector: Record<string, number>;
|
|
152
|
+
gate: Gate | undefined;
|
|
153
|
+
caseGroupMax: number;
|
|
154
|
+
now: number;
|
|
155
|
+
}): TurnDecision;
|
|
156
|
+
//#endregion
|
|
157
|
+
//#region src/overnight.d.ts
|
|
158
|
+
/**
|
|
159
|
+
* maid-voice overnight 产物读取解析(M3c Task 9,规格 §4.1 轻约定 / §4.3 失败语义):
|
|
160
|
+
* 产物 = maid-cron 黎明 job persistTo 按日落档(Task 12 落地写入端)overnight-<YYYY-MM-DD>.txt,
|
|
161
|
+
* 本文件只做读取端。parseOvernight 切分首行(晨报一句)与正文(完整陈述);readOvernight
|
|
162
|
+
* 今日档直读(reused=false),miss 时 onFailure=reuse 取目录内字典序最新档(生成日期距今
|
|
163
|
+
* ≤ staleWindowMs 才用,标 reused=true),empty 或超窗 → undefined。坏文件(空/读失败)
|
|
164
|
+
* 跳过取次新(目录冒名档 readFileSync 抛 EISDIR 同此路)。本文件只 fs,零日志——warn 归
|
|
165
|
+
* 调用方 lifecycle/getMorningSentence 持有(照 loadVoiceState 静默纪律)。
|
|
166
|
+
*
|
|
167
|
+
* 档龄口径(brief 接口无时区参,据此定死):档名日期按 UTC 零点锚与 nowMs 求差——
|
|
168
|
+
* 与宿主时区日界的偏差以时区偏移为上界(上海 8h),相对 36h 默认窗只影响边缘时刻的
|
|
169
|
+
* 昨日档可用性;写入端(maid-cron {{date}})与读取端同宿主时区,日期语义自洽。
|
|
170
|
+
*/
|
|
171
|
+
/**
|
|
172
|
+
* 产物解析(规格 §4.1 轻约定):首行 = 晨报一句,其后正文 = 完整陈述(首尾与分隔空白
|
|
173
|
+
* 容差——空行是书写惯例非硬约束);首行后无正文 → sentence = full = 首行;空/纯空白 →
|
|
174
|
+
* undefined。乱码不在判定面:非空即有首行,轻约定无 schema 可校。
|
|
175
|
+
*/
|
|
176
|
+
declare function parseOvernight(text: string): {
|
|
177
|
+
sentence: string;
|
|
178
|
+
full: string;
|
|
179
|
+
} | undefined;
|
|
180
|
+
/**
|
|
181
|
+
* 读取 + reuse(规格 §4.3):今日档(overnight-<todayKey>.txt)直读,存在且可用 →
|
|
182
|
+
* reused=false;今日档坏(空/读失败)视同 miss。miss 且 onFailure=reuse → 目录扫描合法
|
|
183
|
+
* 档名字典序最新(档名日期 ISO 定宽,字典序即时间序),坏文件跳过取次新,首个可用档
|
|
184
|
+
* 生成日期距今 ≤ staleWindowMs 才用(reused=true);超窗 → undefined(更旧只会更陈,
|
|
185
|
+
* 不再回退)。onFailure=empty → miss 即 undefined。目录缺失/不可读 = 无档可复用。
|
|
186
|
+
*/
|
|
187
|
+
declare function readOvernight(dir: string, todayKey: string, nowMs: number, opts: {
|
|
188
|
+
onFailure: 'reuse' | 'empty';
|
|
189
|
+
staleWindowMs: number;
|
|
190
|
+
}): {
|
|
191
|
+
sentence: string;
|
|
192
|
+
full: string;
|
|
193
|
+
reused: boolean;
|
|
194
|
+
} | undefined;
|
|
195
|
+
//#endregion
|
|
196
|
+
//#region src/lifecycle.d.ts
|
|
197
|
+
/**
|
|
198
|
+
* maid-voice 生命周期(M3c Task 8,规格 §3):agent/pre-step 案例组注入——跃迁才注、
|
|
199
|
+
* 不变不注(decide 决策),引述体单条 user 角色 durable 事件(缓存纪律铁律 3),预算降级
|
|
200
|
+
* 3→1→0。钩子形态照 maid-emotion lifecycle:运行时字符串派发(duck-typing),免 inject
|
|
201
|
+
* 经 deps 探针直读 maidEmotion/maidIdentity 服务(index.ts 接 reflect,maid-gestures 先例)。
|
|
202
|
+
*
|
|
203
|
+
* 情绪投影序由装配序保证(maid-emotion 先挂先注、maid-voice 后挂后注——两条独立 durable
|
|
204
|
+
* 事件,本包测试单挂即可;跨包序断言归 Task 13 快照车道)。Task 11 在同一 handler 加
|
|
205
|
+
* overnight 分支(先于案例组注入,规格 §4.4 通道②:今日叙事未消费 → 完整陈述事件 +
|
|
206
|
+
* overnightConsumedDate 消费标记,同日后续会话不再注;cron 车道守卫链上游豁免,天然不注)。
|
|
207
|
+
*
|
|
208
|
+
* Task 10 服务面:buildNightContext / getMorningSentence 按 maidId 直查(规格 §4.2/§4.4),
|
|
209
|
+
* 供 maid-cron 黎明 job 与晨报渲染消费。cron 黎明 job 是合法调用方,不经 excludeSources——
|
|
210
|
+
* 该守卫只挡会话注入(pre-step),服务面与来源豁免无关(dispatch 补充语义)。
|
|
211
|
+
*/
|
|
212
|
+
declare module '@deepseek-ai/dsh-llm' {
|
|
213
|
+
interface MessageSourceMap {
|
|
214
|
+
'plugin:maid-voice': {
|
|
215
|
+
kind: 'plugin:maid-voice';
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
interface MaidVoiceConfig {
|
|
220
|
+
/** 必填;voice-state 平铺文件(<stateDir>/<maidId>.json)+ overnight 档 per-maid 子目录
|
|
221
|
+
* (<stateDir>/<maidId>/overnight-<date>.txt,fix round 1 多女仆隔离)所在根目录 */
|
|
222
|
+
stateDir: string;
|
|
223
|
+
/** 必填(同 maid-emotion 值;读 voice-overlay.yml / schedule.yml,首中即用) */
|
|
224
|
+
presetRoots: string[];
|
|
225
|
+
/** 同 maid-emotion 语义;缺省全放行 */
|
|
226
|
+
allowMaids?: string[];
|
|
227
|
+
/** 默认 ['cron'](晨报会话与离线叙事生成会话均不注案例,规格 §3.3) */
|
|
228
|
+
excludeSources?: string[];
|
|
229
|
+
/** 案例组上限,默认 3 */
|
|
230
|
+
caseGroupMax?: number;
|
|
231
|
+
/** 注入预算(tokens 估算),默认 150 */
|
|
232
|
+
voiceBudgetTokens?: number;
|
|
233
|
+
/** wilted 域阈值:energy 严格小于即蔫,默认 20 */
|
|
234
|
+
wiltedThreshold?: number;
|
|
235
|
+
/** 四门象限中点(≥ 归高),默认 50 */
|
|
236
|
+
gateMidpoint?: number;
|
|
237
|
+
/** overnight 失败语义(reuse/empty + 复用窗,默认 reuse/36h):服务面(Task 10)与首会话注入(Task 11)同源消费 */
|
|
238
|
+
overnight?: {
|
|
239
|
+
onFailure?: 'reuse' | 'empty';
|
|
240
|
+
staleWindowMs?: number;
|
|
241
|
+
};
|
|
242
|
+
/** 默认 false;开则每轮 logger 一行诊断(gate 四门标签等可读性坐标) */
|
|
243
|
+
debug?: boolean;
|
|
244
|
+
/** 默认 Asia/Shanghai(overnight 日界与 Task 10 晨况消费) */
|
|
245
|
+
timezone?: string;
|
|
246
|
+
/** 时钟注入(测试用);缺省 Date.now() */
|
|
247
|
+
now?: () => number;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* maid-voice 服务面(maid-cron 消费,reflect 可选依赖;service 对象在 attachVoiceLifecycle
|
|
251
|
+
* 闭包内组装。Task 11 再扩展 overnight 会话注入消费)。两方法按 maidId 直查、fail-open:
|
|
252
|
+
* maid 未注册 / 无包配置 / 依赖服务缺 → ''(cron 黎明 job 是合法调用方,不经 excludeSources)。
|
|
253
|
+
*/
|
|
254
|
+
interface MaidVoiceService {
|
|
255
|
+
/** 黎明 job promptTemplate 的 {{nightContext}} 原料(规格 §4.2,五段中文短句 '\n' 拼接) */
|
|
256
|
+
buildNightContext(maidId: string): string;
|
|
257
|
+
/** 晨报 {{overnightSentence}}:今日/复用档首行;无 → ''(fail-open,晨报照发) */
|
|
258
|
+
getMorningSentence(maidId: string): string;
|
|
259
|
+
}
|
|
260
|
+
/** maid-emotion getSnapshot 消费面(M3c Task 3 EmotionSnapshot;本层只吃 vector + reunionTier) */
|
|
261
|
+
interface MaidEmotionLike {
|
|
262
|
+
getSnapshot(maidId: string): EmotionSnapshotLike | undefined;
|
|
263
|
+
}
|
|
264
|
+
/** 情绪只读快照鸭子(Task 3 全字段面;reunionTier 三档或 null=初见/无档) */
|
|
265
|
+
interface EmotionSnapshotLike {
|
|
266
|
+
vector: Record<string, number>;
|
|
267
|
+
trends?: Record<string, 'rising' | 'stable' | 'falling'> | undefined;
|
|
268
|
+
reunionTier: 'soft' | 'distant' | 'estranged' | null;
|
|
269
|
+
sinceLastMessageMs: number;
|
|
270
|
+
lastMasterMessage?: {
|
|
271
|
+
at: number;
|
|
272
|
+
excerpt: string;
|
|
273
|
+
} | undefined;
|
|
274
|
+
lastWeather?: {
|
|
275
|
+
at: number;
|
|
276
|
+
text: string;
|
|
277
|
+
} | undefined;
|
|
278
|
+
calendarSentences: string[];
|
|
279
|
+
timeText: string;
|
|
280
|
+
}
|
|
281
|
+
/** maid-identity 服务面(M3c Task 1:voice 节 + pack 解析;四方法均可选,形状校验归本层) */
|
|
282
|
+
interface MaidIdentityLike {
|
|
283
|
+
maidForPreset?(presetId: string | undefined): {
|
|
284
|
+
maidId: string;
|
|
285
|
+
} | undefined;
|
|
286
|
+
/** Task 10 服务面消费:maidId 直查记录(preset 供 library 文件层定位);缺则按无文件层降级 */
|
|
287
|
+
get?(maidId: string): {
|
|
288
|
+
maidId: string;
|
|
289
|
+
preset: string;
|
|
290
|
+
} | undefined;
|
|
291
|
+
getVoice?(maidId: string): {
|
|
292
|
+
pack?: string;
|
|
293
|
+
worldFlavor?: string;
|
|
294
|
+
} | undefined;
|
|
295
|
+
resolvePack?(packId: string): Record<string, unknown> | undefined;
|
|
296
|
+
}
|
|
297
|
+
interface PreStepPayload {
|
|
298
|
+
agent: {
|
|
299
|
+
id: string;
|
|
300
|
+
session: {
|
|
301
|
+
header: {
|
|
302
|
+
agentPreset?: string;
|
|
303
|
+
};
|
|
304
|
+
snapshotEvents?: () => readonly unknown[];
|
|
305
|
+
};
|
|
306
|
+
};
|
|
307
|
+
messages: Array<{
|
|
308
|
+
content?: Array<{
|
|
309
|
+
type: string;
|
|
310
|
+
text?: string;
|
|
311
|
+
}>;
|
|
312
|
+
source?: {
|
|
313
|
+
kind?: string;
|
|
314
|
+
plugin?: string;
|
|
315
|
+
};
|
|
316
|
+
}>;
|
|
317
|
+
turn: number;
|
|
318
|
+
step: number;
|
|
319
|
+
signal: AbortSignal;
|
|
320
|
+
}
|
|
321
|
+
type PreStepDecision = {
|
|
322
|
+
kind: 'reject';
|
|
323
|
+
} | {
|
|
324
|
+
kind: 'enter';
|
|
325
|
+
messages: unknown[];
|
|
326
|
+
};
|
|
327
|
+
interface VoiceLifecycleContext {
|
|
328
|
+
on(event: 'agent/pre-step', listener: (payload: PreStepPayload, next: () => Promise<PreStepDecision>) => Promise<PreStepDecision>): () => void;
|
|
329
|
+
}
|
|
330
|
+
interface VoiceLifecycleDeps {
|
|
331
|
+
config: MaidVoiceConfig;
|
|
332
|
+
logger: {
|
|
333
|
+
info(message: string): void;
|
|
334
|
+
warn(message: string): void;
|
|
335
|
+
};
|
|
336
|
+
now(): number;
|
|
337
|
+
/** reflect 直读探针(index.ts 接线;per-call 取,晚挂载也能接上;形状校验与 one-shot warn 归本层) */
|
|
338
|
+
emotionOf(): MaidEmotionLike | undefined;
|
|
339
|
+
identityOf(): MaidIdentityLike | undefined;
|
|
340
|
+
}
|
|
341
|
+
declare function attachVoiceLifecycle(ctx: VoiceLifecycleContext, deps: VoiceLifecycleDeps): {
|
|
342
|
+
service: MaidVoiceService;
|
|
343
|
+
dispose(): void;
|
|
344
|
+
};
|
|
345
|
+
//#endregion
|
|
346
|
+
//#region src/index.d.ts
|
|
347
|
+
declare const name = "maid-voice";
|
|
348
|
+
declare const apply: (ctx: any, config: MaidVoiceConfig) => (() => Promise<void>);
|
|
349
|
+
//#endregion
|
|
350
|
+
export { CaseDomain, type EmotionSnapshotLike, Gate, type MaidEmotionLike, type MaidIdentityLike, type MaidVoiceConfig, type MaidVoiceService, OverlayContent, PackCase, PackSchedule, type PreStepDecision, type PreStepPayload, TurnDecision, VoiceLibrary, type VoiceLifecycleContext, type VoiceLifecycleDeps, VoicePack, VoiceState, WhenRange, apply, attachVoiceLifecycle, dateKeyIn, decideTurn, domainOf, gateOf, groupStillMatches, loadVoiceState, name, parseCases, parseOverlay, parseOvernight, parseSchedule, parseVoicePack, readOvernight, resolveVoiceLibrary, saveVoiceState, selectCases };
|