@hchuanz/pocket-core 0.1.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/dist/index.cjs +3583 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1352 -0
- package/dist/index.d.ts +1352 -0
- package/dist/index.js +3487 -0
- package/dist/index.js.map +1 -0
- package/package.json +45 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1352 @@
|
|
|
1
|
+
interface PocketUser {
|
|
2
|
+
userId?: number;
|
|
3
|
+
nickname?: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
phone?: string;
|
|
6
|
+
avatar?: string;
|
|
7
|
+
level?: number;
|
|
8
|
+
money?: number;
|
|
9
|
+
token?: string;
|
|
10
|
+
lastLoginTime?: number;
|
|
11
|
+
}
|
|
12
|
+
interface MemberInfo {
|
|
13
|
+
teamName: string;
|
|
14
|
+
teamId: number;
|
|
15
|
+
serverIcon: string;
|
|
16
|
+
serverId: number;
|
|
17
|
+
serverName: string;
|
|
18
|
+
memberId: number;
|
|
19
|
+
memberName: string;
|
|
20
|
+
}
|
|
21
|
+
interface MemberFlipCustom {
|
|
22
|
+
anonymityCost: number;
|
|
23
|
+
answerType: 1 | 2 | 3;
|
|
24
|
+
baseCost: number;
|
|
25
|
+
normalCost: number;
|
|
26
|
+
privateCost: number;
|
|
27
|
+
status: number;
|
|
28
|
+
}
|
|
29
|
+
interface MemberFlipInfo {
|
|
30
|
+
customs: MemberFlipCustom[];
|
|
31
|
+
}
|
|
32
|
+
interface FlipRecord {
|
|
33
|
+
answerId: string;
|
|
34
|
+
/** 提问 ID:每条翻牌恒定且非空,是唯一可靠的去重键 */
|
|
35
|
+
questionId?: string;
|
|
36
|
+
cost: number;
|
|
37
|
+
answerType: number;
|
|
38
|
+
answerTime: string;
|
|
39
|
+
qtime: string;
|
|
40
|
+
type: number;
|
|
41
|
+
status: number;
|
|
42
|
+
content: string;
|
|
43
|
+
answerContent?: string;
|
|
44
|
+
baseUserInfo?: {
|
|
45
|
+
userId: number;
|
|
46
|
+
nickname: string;
|
|
47
|
+
avatar: string;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
interface FlipCardGroup {
|
|
51
|
+
xoxId: number;
|
|
52
|
+
xoxNickname: string;
|
|
53
|
+
cards: Array<{
|
|
54
|
+
answerId: string;
|
|
55
|
+
cost: number;
|
|
56
|
+
answerType: number;
|
|
57
|
+
answerTime: string;
|
|
58
|
+
qtime: string;
|
|
59
|
+
type: number;
|
|
60
|
+
}>;
|
|
61
|
+
}
|
|
62
|
+
interface DashboardInfo {
|
|
63
|
+
totalFlipCount: number;
|
|
64
|
+
runningCount: number;
|
|
65
|
+
returnedCount: number;
|
|
66
|
+
costTotal: number;
|
|
67
|
+
}
|
|
68
|
+
interface FlipCacheMeta {
|
|
69
|
+
syncedAt: number;
|
|
70
|
+
recordCount: number;
|
|
71
|
+
}
|
|
72
|
+
interface FlipUserCache {
|
|
73
|
+
userId: string;
|
|
74
|
+
records: FlipRecord[];
|
|
75
|
+
groupedDataById: Record<string, FlipCardGroup>;
|
|
76
|
+
dashboardInfo: DashboardInfo;
|
|
77
|
+
meta: FlipCacheMeta;
|
|
78
|
+
}
|
|
79
|
+
type FlipSyncMode = 'incremental' | 'full';
|
|
80
|
+
interface FlipSearchParams {
|
|
81
|
+
pageSize?: number;
|
|
82
|
+
pageNum?: number;
|
|
83
|
+
xoxId?: number;
|
|
84
|
+
startTimeMs?: number;
|
|
85
|
+
endTimeMs?: number;
|
|
86
|
+
type?: number;
|
|
87
|
+
status?: number;
|
|
88
|
+
answerType?: number;
|
|
89
|
+
keyword?: string;
|
|
90
|
+
}
|
|
91
|
+
interface FlipSendParams {
|
|
92
|
+
memberId: string;
|
|
93
|
+
content: string;
|
|
94
|
+
type: number;
|
|
95
|
+
cost: string;
|
|
96
|
+
answerType: number;
|
|
97
|
+
}
|
|
98
|
+
interface MemberSearchParams {
|
|
99
|
+
teamId?: number;
|
|
100
|
+
memberName?: string;
|
|
101
|
+
isFavorite?: boolean;
|
|
102
|
+
}
|
|
103
|
+
interface RoomJumpResult {
|
|
104
|
+
channelId: number;
|
|
105
|
+
serverId?: number;
|
|
106
|
+
}
|
|
107
|
+
interface RoomChannelInfo {
|
|
108
|
+
channelId: number;
|
|
109
|
+
channelName: string;
|
|
110
|
+
serverId: number;
|
|
111
|
+
teamId: number;
|
|
112
|
+
ownerId: number;
|
|
113
|
+
ownerName: string;
|
|
114
|
+
channelPocketType: number;
|
|
115
|
+
channelStatus: number;
|
|
116
|
+
serverType: number;
|
|
117
|
+
functionType: string;
|
|
118
|
+
bgImg: string;
|
|
119
|
+
pocketAccessMode: number;
|
|
120
|
+
hasMsgBoard: number;
|
|
121
|
+
activitySwitch: boolean;
|
|
122
|
+
}
|
|
123
|
+
interface RoomMessageSender {
|
|
124
|
+
userId: number;
|
|
125
|
+
nickName: string;
|
|
126
|
+
avatar: string;
|
|
127
|
+
level?: number;
|
|
128
|
+
}
|
|
129
|
+
interface RoomLiveInfo {
|
|
130
|
+
liveId?: string;
|
|
131
|
+
liveTitle?: string;
|
|
132
|
+
liveCover?: string;
|
|
133
|
+
shortPath?: string;
|
|
134
|
+
}
|
|
135
|
+
interface RoomGiftInfo {
|
|
136
|
+
giftName?: string;
|
|
137
|
+
giftNum?: number;
|
|
138
|
+
giftPic?: string;
|
|
139
|
+
}
|
|
140
|
+
interface RoomReplyInfo {
|
|
141
|
+
replyName?: string;
|
|
142
|
+
replyText?: string;
|
|
143
|
+
replyMessageId?: string;
|
|
144
|
+
}
|
|
145
|
+
interface RoomMessage {
|
|
146
|
+
msgId: string;
|
|
147
|
+
msgTime: number;
|
|
148
|
+
msgType: string;
|
|
149
|
+
text?: string;
|
|
150
|
+
mediaUrl?: string;
|
|
151
|
+
mediaDuration?: number;
|
|
152
|
+
liveInfo?: RoomLiveInfo;
|
|
153
|
+
giftInfo?: RoomGiftInfo;
|
|
154
|
+
replyInfo?: RoomReplyInfo;
|
|
155
|
+
sender?: RoomMessageSender;
|
|
156
|
+
}
|
|
157
|
+
interface RoomMessagePage {
|
|
158
|
+
messages: RoomMessage[];
|
|
159
|
+
nextTime: number;
|
|
160
|
+
}
|
|
161
|
+
interface PocketApiResponse<T = unknown> {
|
|
162
|
+
success?: boolean;
|
|
163
|
+
status?: number;
|
|
164
|
+
message?: string;
|
|
165
|
+
content?: T;
|
|
166
|
+
data?: {
|
|
167
|
+
content?: T;
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/** 网易云信 IM 登录凭证(/im/api/v1/im/userinfo 下发),用于登 NIM 长连接 */
|
|
171
|
+
interface ImUserInfo {
|
|
172
|
+
accid: string;
|
|
173
|
+
pwd: string;
|
|
174
|
+
userId: number;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
interface ModelConfig {
|
|
178
|
+
baseUrl: string;
|
|
179
|
+
apiKey: string;
|
|
180
|
+
chatModel: string;
|
|
181
|
+
reasoningModel: string;
|
|
182
|
+
embeddingModel: string;
|
|
183
|
+
lightweightModel: string;
|
|
184
|
+
mirrorMode: string;
|
|
185
|
+
analysisTemperature?: number;
|
|
186
|
+
chatTemperature?: number;
|
|
187
|
+
}
|
|
188
|
+
interface ChatMessage {
|
|
189
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
190
|
+
content: string;
|
|
191
|
+
tool_call_id?: string;
|
|
192
|
+
tool_calls?: Array<{
|
|
193
|
+
id: string;
|
|
194
|
+
type: 'function';
|
|
195
|
+
function: {
|
|
196
|
+
name: string;
|
|
197
|
+
arguments: string;
|
|
198
|
+
};
|
|
199
|
+
}>;
|
|
200
|
+
}
|
|
201
|
+
interface ToolDefinition {
|
|
202
|
+
type: 'function';
|
|
203
|
+
function: {
|
|
204
|
+
name: string;
|
|
205
|
+
description: string;
|
|
206
|
+
parameters: Record<string, unknown>;
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
interface ChatCompletionChunk {
|
|
210
|
+
content: string;
|
|
211
|
+
toolCalls: Array<{
|
|
212
|
+
index: number;
|
|
213
|
+
id: string;
|
|
214
|
+
name: string;
|
|
215
|
+
arguments: string;
|
|
216
|
+
}>;
|
|
217
|
+
isDone: boolean;
|
|
218
|
+
}
|
|
219
|
+
type MirrorMode = 'economy' | 'performance';
|
|
220
|
+
|
|
221
|
+
interface MirrorPersona {
|
|
222
|
+
personalityTraits: string[];
|
|
223
|
+
speechPatterns: string[];
|
|
224
|
+
signaturePhrases: string[];
|
|
225
|
+
emotionalTone: string;
|
|
226
|
+
personaSummary: string;
|
|
227
|
+
relationship?: MirrorRelationship;
|
|
228
|
+
recentActivity?: MirrorRecentActivity;
|
|
229
|
+
}
|
|
230
|
+
interface MirrorRelationship {
|
|
231
|
+
dynamic: string;
|
|
232
|
+
closeness: number;
|
|
233
|
+
howSheAddressesMe: string;
|
|
234
|
+
topicsWeDiscuss: string[];
|
|
235
|
+
evolution: string;
|
|
236
|
+
}
|
|
237
|
+
interface MirrorRecentActivity {
|
|
238
|
+
topics: string[];
|
|
239
|
+
mood: string;
|
|
240
|
+
events: string[];
|
|
241
|
+
}
|
|
242
|
+
interface MirrorProfile {
|
|
243
|
+
xoxId: number;
|
|
244
|
+
xoxNickname: string;
|
|
245
|
+
persona: MirrorPersona;
|
|
246
|
+
previousPersona?: MirrorPersona;
|
|
247
|
+
fewShotExamples: Array<{
|
|
248
|
+
userQuestion: string;
|
|
249
|
+
idolReply: string;
|
|
250
|
+
relevance: number;
|
|
251
|
+
}>;
|
|
252
|
+
meta: {
|
|
253
|
+
totalSamplesUsed: number;
|
|
254
|
+
lastUpdatedAt: number;
|
|
255
|
+
dataRangeMs: [number, number];
|
|
256
|
+
maturityScore: number;
|
|
257
|
+
};
|
|
258
|
+
growthLog?: GrowthEvent[];
|
|
259
|
+
}
|
|
260
|
+
interface GrowthEvent {
|
|
261
|
+
timestamp: number;
|
|
262
|
+
reason: string;
|
|
263
|
+
changes: string[];
|
|
264
|
+
}
|
|
265
|
+
interface ChatSession {
|
|
266
|
+
sessionId: string;
|
|
267
|
+
xoxId: number;
|
|
268
|
+
messages: Array<{
|
|
269
|
+
role: string;
|
|
270
|
+
content: string;
|
|
271
|
+
}>;
|
|
272
|
+
createdAt: number;
|
|
273
|
+
lastActiveAt: number;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Normalize a persona from disk or LLM output.
|
|
277
|
+
* Old profiles / incomplete LLM responses may miss fields; fill in safe defaults
|
|
278
|
+
* so downstream consumers (chat prompt builder, frontend render) never crash.
|
|
279
|
+
*/
|
|
280
|
+
declare function normalizePersona(persona: Partial<MirrorPersona> | null | undefined): MirrorPersona;
|
|
281
|
+
interface MirrorConfig {
|
|
282
|
+
/** LLM analysis: max flip records to sample for persona extraction */
|
|
283
|
+
llmSampleSize: number;
|
|
284
|
+
/** LLM analysis: max_tokens for the analysis response */
|
|
285
|
+
llmMaxTokens: number;
|
|
286
|
+
/** LLM analysis: temperature (0=deterministic, 1=creative) */
|
|
287
|
+
analysisTemperature: number;
|
|
288
|
+
/** Chat: max rounds of conversation history to keep */
|
|
289
|
+
chatHistoryRounds: number;
|
|
290
|
+
/** Chat: temperature (0=deterministic, 1=creative) */
|
|
291
|
+
chatTemperature: number;
|
|
292
|
+
/** RAG: top-K results to retrieve from vector index */
|
|
293
|
+
ragTopK: number;
|
|
294
|
+
/** RAG: minimum cosine similarity score to include a result */
|
|
295
|
+
ragMinScore: number;
|
|
296
|
+
/** Episodic memory: max recent conversation summaries to inject */
|
|
297
|
+
memoryEpisodes: number;
|
|
298
|
+
/** Embedding: max records to build vector index for (0 = unlimited) */
|
|
299
|
+
embeddingMaxRecords: number;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Pocket48 客户端常量
|
|
304
|
+
*
|
|
305
|
+
* 来自反编译的 Android APK(com.pocket.snh48),
|
|
306
|
+
* 这些是客户端签名常量,不是用户密码或 API Key。
|
|
307
|
+
*
|
|
308
|
+
* ⚠ 安全提示:真实 token / apiKey / 用户密码不得写入此文件。
|
|
309
|
+
* apiKey 仅由 ISecureStorage 管理,token 由 IConfigStore 管理。
|
|
310
|
+
*/
|
|
311
|
+
/** 所有业务接口前缀 */
|
|
312
|
+
declare const POCKET_API_BASE = "https://pocketapi.48.cn";
|
|
313
|
+
/** 头像/图片相对路径必须拼此前缀(如 /content/images/xxx.png → https://source.48.cn/content/images/xxx.png) */
|
|
314
|
+
declare const AVA_BASE_URL = "https://source.48.cn";
|
|
315
|
+
/** 客户端描述 JSON(deviceId 为固定值,非用户设备) */
|
|
316
|
+
declare const POCKET_APP_INFO: string;
|
|
317
|
+
/** 客户端签名 pa 头(静态值,非密码学签名) */
|
|
318
|
+
declare const POCKET_PA = "MTc4MjM3NDEwNjAwMCw3NzE1LEIwODM5QzdEMjZFQzJFOTFERTExNDVERDU2NTlBRjk5LA==";
|
|
319
|
+
/** User-Agent */
|
|
320
|
+
declare const POCKET_USER_AGENT = "PocketFans201807/7.1.37 (iPhone; iOS 26.4; Scale/3.00)";
|
|
321
|
+
/** token 本地过期时间 */
|
|
322
|
+
declare const SESSION_EXPIRE_MS: number;
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* 日志端口。
|
|
326
|
+
*
|
|
327
|
+
* 对应原 hchuanz-pocket-helper 中的 `ee-core/log` 的 logger
|
|
328
|
+
* (`logger.debug/info/warn/error`)。core 只消费本接口,不依赖任何日志库。
|
|
329
|
+
*/
|
|
330
|
+
interface ILogger {
|
|
331
|
+
debug(...args: unknown[]): void;
|
|
332
|
+
info(...args: unknown[]): void;
|
|
333
|
+
warn(...args: unknown[]): void;
|
|
334
|
+
error(...args: unknown[]): void;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* 存储端口。
|
|
339
|
+
*
|
|
340
|
+
* 抽象 Electron 的 `app.getPath('userData')` + Node `fs`/`path`。
|
|
341
|
+
* core 内所有镜像/翻牌/会话/群聊的 JSON 持久化都收敛到本接口,
|
|
342
|
+
* 业务模块禁止直接 import `fs` / `path`。
|
|
343
|
+
*
|
|
344
|
+
* subpath 相对 `root`,对应原代码里 `path.join(app.getPath('userData'), ...)` 的相对部分。
|
|
345
|
+
*/
|
|
346
|
+
interface IStorage {
|
|
347
|
+
/** 存储根路径(对应 userData 目录) */
|
|
348
|
+
readonly root: string;
|
|
349
|
+
/** 读取 JSON 文件,不存在或解析失败返回 null */
|
|
350
|
+
readJson<T = unknown>(subpath: string): T | null;
|
|
351
|
+
/** 写入 JSON(缩进 2 空格,对齐原 writeFileSync(..., JSON.stringify(x, null, 2))) */
|
|
352
|
+
writeJson(subpath: string, data: unknown): void;
|
|
353
|
+
exists(subpath: string): boolean;
|
|
354
|
+
delete(subpath: string): void;
|
|
355
|
+
/** 列出目录下所有文件名(不含子目录) */
|
|
356
|
+
list(dirSubpath: string): string[];
|
|
357
|
+
/** 递归创建目录 */
|
|
358
|
+
mkdir(dirSubpath: string): void;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* 安全存储端口。
|
|
363
|
+
*
|
|
364
|
+
* 抽象 Electron 的 `safeStorage`(`encryptString/decryptString`),
|
|
365
|
+
* 用于加密用户 LLM API Key。core 只消费本接口,Electron 实现留在原仓库。
|
|
366
|
+
*
|
|
367
|
+
* 返回 base64 字符串,对齐 `safeStorage.encryptString(...).toString('base64')`。
|
|
368
|
+
*/
|
|
369
|
+
interface ISecureStorage {
|
|
370
|
+
/** 是否可用(对应 safeStorage.isEncryptionAvailable()) */
|
|
371
|
+
isAvailable(): boolean;
|
|
372
|
+
encryptString(plain: string): string;
|
|
373
|
+
decryptString(encoded: string): string;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* KV 配置存储端口。
|
|
378
|
+
*
|
|
379
|
+
* 抽象原 hchuanz-pocket-helper 的 `storeService`(ee-core),
|
|
380
|
+
* 用于保存模型配置、推送配置、token 等 key-value 数据。
|
|
381
|
+
*
|
|
382
|
+
* 原 `set` 有 `persist` 参数(内存/持久分层),新接口简化为默认持久化;
|
|
383
|
+
* 纯内存场景由 adapters 的 MemoryConfigStore 单独提供。
|
|
384
|
+
*/
|
|
385
|
+
interface IConfigStore {
|
|
386
|
+
get<T = unknown>(key: string): T | undefined;
|
|
387
|
+
set(key: string, value: unknown): void;
|
|
388
|
+
remove(key: string): void;
|
|
389
|
+
has(key: string): boolean;
|
|
390
|
+
clear(): void;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* 翻牌数据源端口。
|
|
395
|
+
*
|
|
396
|
+
* 抽象原 hchuanz-pocket-helper 的 `flipCacheService`,
|
|
397
|
+
* 只保留裸读写(按 userId 分桶);dashboard 统计、groupDataById 聚合等纯逻辑
|
|
398
|
+
* 由 core 内业务模块负责。
|
|
399
|
+
*/
|
|
400
|
+
interface IFlipDataSource {
|
|
401
|
+
get(userId: string): FlipUserCache | null;
|
|
402
|
+
set(cache: FlipUserCache): void;
|
|
403
|
+
clear(userId: string): void;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
interface ChatCompletionOptions {
|
|
407
|
+
model?: string;
|
|
408
|
+
maxTokens?: number;
|
|
409
|
+
temperature?: number;
|
|
410
|
+
timeoutMs?: number;
|
|
411
|
+
}
|
|
412
|
+
interface ChatCompletionResult {
|
|
413
|
+
content: string;
|
|
414
|
+
toolCalls: ChatMessage['tool_calls'];
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* LLM 客户端端口。
|
|
418
|
+
*
|
|
419
|
+
* 抽象原 hchuanz-pocket-helper 的 `common/providers.ts`(OpenAI 兼容 API)。
|
|
420
|
+
* core 通过本接口完成对话/流式/embedding/连通性测试,
|
|
421
|
+
* 具体实现走原生 fetch(OpenAICompatibleClient)。
|
|
422
|
+
*/
|
|
423
|
+
interface ILlmClient {
|
|
424
|
+
chatCompletion(config: ModelConfig, messages: ChatMessage[], tools?: ToolDefinition[], options?: ChatCompletionOptions): Promise<ChatCompletionResult>;
|
|
425
|
+
chatCompletionStream(config: ModelConfig, messages: ChatMessage[], onChunk: (chunk: ChatCompletionChunk) => void, tools?: ToolDefinition[], options?: ChatCompletionOptions): Promise<ChatMessage['tool_calls']>;
|
|
426
|
+
embed(config: ModelConfig, texts: string[], model?: string): Promise<number[][]>;
|
|
427
|
+
testConnection(config: ModelConfig): Promise<{
|
|
428
|
+
ok: boolean;
|
|
429
|
+
message: string;
|
|
430
|
+
}>;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* 流式聊天输出端口。
|
|
435
|
+
*
|
|
436
|
+
* 抽象原 hchuanz-pocket-helper 里 mirrorChat 的流式回调
|
|
437
|
+
* (`onChunk(content, isDone, newSessionId)`)。
|
|
438
|
+
* Electron 侧把 `IChatStreamSink` 包一层 `webContents.send`。
|
|
439
|
+
*/
|
|
440
|
+
interface IChatStreamSink {
|
|
441
|
+
onChunk(content: string, isDone: boolean, newSessionId?: string): void;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* 事件推送端口。
|
|
445
|
+
*
|
|
446
|
+
* 抽象 Electron 的 `BrowserWindow.webContents.send(channel, payload)`,
|
|
447
|
+
* 用于群聊等场景把结构化事件推给渲染进程。
|
|
448
|
+
*/
|
|
449
|
+
interface IEventSink {
|
|
450
|
+
emit(channel: string, payload: unknown): void;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* 认证过期处理端口。
|
|
455
|
+
*
|
|
456
|
+
* 抽象原 hchuanz-pocket-helper 中 `kickToLogin()` 的逻辑:
|
|
457
|
+
* toast 提示 + 清登录态 + 跳登录页。core 只定义回调接口,
|
|
458
|
+
* 具体实现由宿主(Electron / MCP CLI)注入。
|
|
459
|
+
*/
|
|
460
|
+
interface IAuthExpiredHandler {
|
|
461
|
+
/** 登录过期回调。宿主负责 toast + 清登录态 + 跳登录页 */
|
|
462
|
+
onAuthExpired(): void;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/** 直打 console,适用本地/CLI/MCP 场景 */
|
|
466
|
+
declare class ConsoleLogger implements ILogger {
|
|
467
|
+
debug(...args: unknown[]): void;
|
|
468
|
+
info(...args: unknown[]): void;
|
|
469
|
+
warn(...args: unknown[]): void;
|
|
470
|
+
error(...args: unknown[]): void;
|
|
471
|
+
}
|
|
472
|
+
/** 空实现,测试或静默场景 */
|
|
473
|
+
declare class NoopLogger implements ILogger {
|
|
474
|
+
debug(): void;
|
|
475
|
+
info(): void;
|
|
476
|
+
warn(): void;
|
|
477
|
+
error(): void;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Node JSON 文件存储。
|
|
482
|
+
*
|
|
483
|
+
* 对齐原 hchuanz-pocket-helper 的 `mirrorStore` / `flipCache` 等 fs 读写习惯:
|
|
484
|
+
* JSON 缩进 2 空格、不存在返回 null、读取失败返回 null。
|
|
485
|
+
*/
|
|
486
|
+
declare class NodeJsonFileStorage implements IStorage {
|
|
487
|
+
readonly root: string;
|
|
488
|
+
constructor(root: string);
|
|
489
|
+
private resolve;
|
|
490
|
+
readJson<T = unknown>(subpath: string): T | null;
|
|
491
|
+
writeJson(subpath: string, data: unknown): void;
|
|
492
|
+
exists(subpath: string): boolean;
|
|
493
|
+
delete(subpath: string): void;
|
|
494
|
+
list(dirSubpath: string): string[];
|
|
495
|
+
mkdir(dirSubpath: string): void;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* 明文安全存储(dev/test 参考实现)。
|
|
500
|
+
*
|
|
501
|
+
* ⚠ 仅 base64 编码,**不是真加密**,禁止用于生产环境敏感数据。
|
|
502
|
+
* 生产用 Electron 的 safeStorage 实现(留在原仓库)。
|
|
503
|
+
*/
|
|
504
|
+
declare class PlainTextSecureStorage implements ISecureStorage {
|
|
505
|
+
isAvailable(): boolean;
|
|
506
|
+
encryptString(plain: string): string;
|
|
507
|
+
decryptString(encoded: string): string;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Node JSON KV 配置存储。
|
|
512
|
+
*
|
|
513
|
+
* 对齐原 hchuanz-pocket-helper 的 `storeService`:持久化到单个 `app-store.json`,
|
|
514
|
+
* get 不存在返回 undefined。
|
|
515
|
+
*/
|
|
516
|
+
declare class NodeJsonConfigStore implements IConfigStore {
|
|
517
|
+
private readonly filePath;
|
|
518
|
+
private data;
|
|
519
|
+
private loaded;
|
|
520
|
+
constructor(root: string, filename?: string);
|
|
521
|
+
private ensureLoaded;
|
|
522
|
+
private save;
|
|
523
|
+
get<T = unknown>(key: string): T | undefined;
|
|
524
|
+
set(key: string, value: unknown): void;
|
|
525
|
+
remove(key: string): void;
|
|
526
|
+
has(key: string): boolean;
|
|
527
|
+
clear(): void;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/** 纯内存 KV 存储,给 MCP 无磁盘场景 / 测试 */
|
|
531
|
+
declare class MemoryConfigStore implements IConfigStore {
|
|
532
|
+
private data;
|
|
533
|
+
get<T = unknown>(key: string): T | undefined;
|
|
534
|
+
set(key: string, value: unknown): void;
|
|
535
|
+
remove(key: string): void;
|
|
536
|
+
has(key: string): boolean;
|
|
537
|
+
clear(): void;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/** 兼容旧存储的读取器(allUserData/groupedDataById/dashboardInfo 迁移),可空 */
|
|
541
|
+
type LegacyFlipReader = () => {
|
|
542
|
+
allUserData?: Record<string, unknown[]>;
|
|
543
|
+
groupedDataById?: Record<string, unknown>;
|
|
544
|
+
dashboardInfo?: FlipUserCache['dashboardInfo'];
|
|
545
|
+
} | null;
|
|
546
|
+
/**
|
|
547
|
+
* Node JSON 翻牌数据源。
|
|
548
|
+
*
|
|
549
|
+
* 对齐原 hchuanz-pocket-helper 的 `flipCacheService`:
|
|
550
|
+
* `flip-cache/{userId}.json`,构造可注入 legacy 读取器做旧数据迁移。
|
|
551
|
+
*/
|
|
552
|
+
declare class NodeJsonFlipDataSource implements IFlipDataSource {
|
|
553
|
+
private readonly storage;
|
|
554
|
+
private readonly readLegacy?;
|
|
555
|
+
constructor(storage: IStorage, readLegacy?: LegacyFlipReader);
|
|
556
|
+
private filePath;
|
|
557
|
+
get(userId: string): FlipUserCache | null;
|
|
558
|
+
set(cache: FlipUserCache): void;
|
|
559
|
+
clear(userId: string): void;
|
|
560
|
+
private migrateFromLegacy;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/** 纯内存翻牌数据源,给 MCP 无磁盘场景 / 测试 */
|
|
564
|
+
declare class MemoryFlipDataSource implements IFlipDataSource {
|
|
565
|
+
private data;
|
|
566
|
+
get(userId: string): FlipUserCache | null;
|
|
567
|
+
set(cache: FlipUserCache): void;
|
|
568
|
+
clear(userId: string): void;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* OpenAI 兼容 LLM 客户端。
|
|
573
|
+
*
|
|
574
|
+
* 对齐原 hchuanz-pocket-helper 的 `common/providers.ts`:
|
|
575
|
+
* chatCompletion / chatCompletionStream / embed / testConnection,
|
|
576
|
+
* 全部走原生 fetch,零依赖。
|
|
577
|
+
*/
|
|
578
|
+
declare class OpenAICompatibleClient implements ILlmClient {
|
|
579
|
+
private readonly logger;
|
|
580
|
+
constructor(logger: ILogger);
|
|
581
|
+
chatCompletion(config: ModelConfig, messages: ChatMessage[], tools?: ToolDefinition[], options?: ChatCompletionOptions): Promise<ChatCompletionResult>;
|
|
582
|
+
chatCompletionStream(config: ModelConfig, messages: ChatMessage[], onChunk: (chunk: ChatCompletionChunk) => void, tools?: ToolDefinition[], options?: ChatCompletionOptions): Promise<ChatMessage['tool_calls']>;
|
|
583
|
+
embed(config: ModelConfig, texts: string[], model?: string): Promise<number[][]>;
|
|
584
|
+
testConnection(config: ModelConfig): Promise<{
|
|
585
|
+
ok: boolean;
|
|
586
|
+
message: string;
|
|
587
|
+
}>;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* 回调流输出。
|
|
592
|
+
*
|
|
593
|
+
* 把 `IChatStreamSink` 桥接到回调函数,供测试或直接消费(非 IPC)。
|
|
594
|
+
*/
|
|
595
|
+
declare class CallbackStreamSink implements IChatStreamSink {
|
|
596
|
+
private readonly onChunkCb;
|
|
597
|
+
constructor(cb: (content: string, isDone: boolean, newSessionId?: string) => void);
|
|
598
|
+
onChunk(content: string, isDone: boolean, newSessionId?: string): void;
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* 事件推送空实现(MCP/测试场景无 UI 渲染进程)。
|
|
602
|
+
*/
|
|
603
|
+
declare class NoopEventSink implements IEventSink {
|
|
604
|
+
emit(): void;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Runtime tool descriptor with handler
|
|
609
|
+
*/
|
|
610
|
+
interface RegisteredTool extends ToolDefinition {
|
|
611
|
+
category: 'platform' | 'mirror' | 'user' | 'pocket';
|
|
612
|
+
handler: (args: Record<string, unknown>, context: ToolContext) => Promise<unknown>;
|
|
613
|
+
}
|
|
614
|
+
interface ToolContext {
|
|
615
|
+
userId: string;
|
|
616
|
+
signal?: AbortSignal;
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* 工具注册中心。
|
|
620
|
+
*
|
|
621
|
+
* 负责注册、查询、执行 Agent 工具。通过依赖注入接收 ILogger,
|
|
622
|
+
* 替代原 hchuanz-pocket-helper 中直接 import ee-core/log 的实现。
|
|
623
|
+
*/
|
|
624
|
+
declare class ToolRegistry {
|
|
625
|
+
private logger;
|
|
626
|
+
private tools;
|
|
627
|
+
constructor(logger: ILogger);
|
|
628
|
+
/**
|
|
629
|
+
* Register a tool (platform / agent / user MCP)
|
|
630
|
+
*/
|
|
631
|
+
register(tool: RegisteredTool): void;
|
|
632
|
+
/**
|
|
633
|
+
* Bulk register tools from an array
|
|
634
|
+
*/
|
|
635
|
+
registerAll(tools: RegisteredTool[]): void;
|
|
636
|
+
/**
|
|
637
|
+
* Unregister a tool by name
|
|
638
|
+
*/
|
|
639
|
+
unregister(name: string): void;
|
|
640
|
+
/**
|
|
641
|
+
* Unregister all tools with a given prefix (e.g. MCP server name)
|
|
642
|
+
*/
|
|
643
|
+
unregisterByPrefix(prefix: string): void;
|
|
644
|
+
/**
|
|
645
|
+
* Get a single tool by name
|
|
646
|
+
*/
|
|
647
|
+
get(name: string): RegisteredTool | undefined;
|
|
648
|
+
/**
|
|
649
|
+
* Get all tools in OpenAI function-calling format
|
|
650
|
+
*/
|
|
651
|
+
getOpenAIFormat(): ToolDefinition[];
|
|
652
|
+
/**
|
|
653
|
+
* Get tools filtered by category
|
|
654
|
+
*/
|
|
655
|
+
getByCategory(category: RegisteredTool['category']): ToolDefinition[];
|
|
656
|
+
/**
|
|
657
|
+
* Execute a tool by name
|
|
658
|
+
*/
|
|
659
|
+
execute(name: string, args: Record<string, unknown>, context: ToolContext): Promise<unknown>;
|
|
660
|
+
/**
|
|
661
|
+
* List all registered tool names
|
|
662
|
+
*/
|
|
663
|
+
listNames(): string[];
|
|
664
|
+
/**
|
|
665
|
+
* Clear all tools
|
|
666
|
+
*/
|
|
667
|
+
clear(): void;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* 镜像档案与聊天会话持久化存储。
|
|
672
|
+
*
|
|
673
|
+
* 通过 IStorage 抽象底层文件系统,替代原 hchuanz-pocket-helper 中
|
|
674
|
+
* `app.getPath('userData')` + `fs` 的直接调用。
|
|
675
|
+
*/
|
|
676
|
+
declare class MirrorStore {
|
|
677
|
+
private storage;
|
|
678
|
+
private logger;
|
|
679
|
+
constructor(storage: IStorage, logger: ILogger);
|
|
680
|
+
getProfile(xoxId: number, userId: string): MirrorProfile | null;
|
|
681
|
+
saveProfile(profile: MirrorProfile, userId: string): void;
|
|
682
|
+
deleteProfile(xoxId: number, userId: string): void;
|
|
683
|
+
listProfiles(userId: string): MirrorProfile[];
|
|
684
|
+
getSession(sessionId: string, userId: string): ChatSession | null;
|
|
685
|
+
saveSession(session: ChatSession, userId: string): void;
|
|
686
|
+
/**
|
|
687
|
+
* Find the most recently active chat session for an idol
|
|
688
|
+
*/
|
|
689
|
+
getLatestSessionForXox(xoxId: number, userId: string): ChatSession | null;
|
|
690
|
+
deleteSession(sessionId: string, userId: string): void;
|
|
691
|
+
/**
|
|
692
|
+
* Delete all chat sessions for an idol (keeps profile)
|
|
693
|
+
*/
|
|
694
|
+
deleteSessionsForXox(xoxId: number, userId: string): void;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
interface FlipRecordVector {
|
|
698
|
+
answerId: string;
|
|
699
|
+
content: string;
|
|
700
|
+
answerContent: string;
|
|
701
|
+
qtime: number;
|
|
702
|
+
hash: string;
|
|
703
|
+
vector: number[];
|
|
704
|
+
}
|
|
705
|
+
interface SearchHit {
|
|
706
|
+
record: FlipRecordVector;
|
|
707
|
+
score: number;
|
|
708
|
+
}
|
|
709
|
+
interface IndexFile {
|
|
710
|
+
xoxId: number;
|
|
711
|
+
model: string;
|
|
712
|
+
updatedAt: number;
|
|
713
|
+
vectors: FlipRecordVector[];
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* 向量索引服务。
|
|
717
|
+
*
|
|
718
|
+
* 通过 ILlmClient 调用 embedding API 构建/搜索翻牌记录的语义向量索引,
|
|
719
|
+
* 支持 cosine + MMR 的 top-K 检索。
|
|
720
|
+
* 底层持久化通过 IStorage,替代原 hchuanz-pocket-helper 中 `fs` + `app.getPath`。
|
|
721
|
+
*/
|
|
722
|
+
declare class MirrorIndex {
|
|
723
|
+
private storage;
|
|
724
|
+
private logger;
|
|
725
|
+
private llmClient;
|
|
726
|
+
constructor(storage: IStorage, logger: ILogger, llmClient: ILlmClient);
|
|
727
|
+
/**
|
|
728
|
+
* Load index from disk (returns null if not exists)
|
|
729
|
+
*/
|
|
730
|
+
load(xoxId: number): IndexFile | null;
|
|
731
|
+
/**
|
|
732
|
+
* Build / incrementally update the vector index for an idol's flip records.
|
|
733
|
+
* Records with unchanged hash reuse existing embeddings.
|
|
734
|
+
*/
|
|
735
|
+
buildIndex(xoxId: number, config: ModelConfig, records: Array<{
|
|
736
|
+
answerId?: string;
|
|
737
|
+
content?: string;
|
|
738
|
+
answerContent?: string;
|
|
739
|
+
qtime?: number | string;
|
|
740
|
+
}>): Promise<{
|
|
741
|
+
indexed: number;
|
|
742
|
+
reused: number;
|
|
743
|
+
}>;
|
|
744
|
+
/**
|
|
745
|
+
* Delete index for an idol
|
|
746
|
+
*/
|
|
747
|
+
deleteIndex(xoxId: number): void;
|
|
748
|
+
/**
|
|
749
|
+
* Search with cosine top-K + MMR dedup
|
|
750
|
+
*/
|
|
751
|
+
search(xoxId: number, config: ModelConfig, query: string, topK?: number): Promise<SearchHit[]>;
|
|
752
|
+
/**
|
|
753
|
+
* Get index stats
|
|
754
|
+
*/
|
|
755
|
+
getStats(xoxId: number): {
|
|
756
|
+
total: number;
|
|
757
|
+
updatedAt: number;
|
|
758
|
+
} | null;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
interface EpisodicEntry {
|
|
762
|
+
id: string;
|
|
763
|
+
topic: string;
|
|
764
|
+
summary: string;
|
|
765
|
+
turns: number;
|
|
766
|
+
createdAt: number;
|
|
767
|
+
}
|
|
768
|
+
interface MemoryFile {
|
|
769
|
+
xoxId: number;
|
|
770
|
+
totalTurns: number;
|
|
771
|
+
episodes: EpisodicEntry[];
|
|
772
|
+
updatedAt: number;
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* 情节记忆服务。
|
|
776
|
+
*
|
|
777
|
+
* 记录对话轮次,定期调用 LLM 将对话压缩为情节记忆条目,提供检索和清理。
|
|
778
|
+
* 底层持久化通过 IStorage,LLM 调用通过 ILlmClient。
|
|
779
|
+
*/
|
|
780
|
+
declare class MirrorMemory {
|
|
781
|
+
private storage;
|
|
782
|
+
private logger;
|
|
783
|
+
private llmClient;
|
|
784
|
+
constructor(storage: IStorage, logger: ILogger, llmClient: ILlmClient);
|
|
785
|
+
private ensureDir;
|
|
786
|
+
/**
|
|
787
|
+
* Load memory file
|
|
788
|
+
*/
|
|
789
|
+
load(xoxId: number): MemoryFile;
|
|
790
|
+
private save;
|
|
791
|
+
/**
|
|
792
|
+
* Increment turn counter (called after each chat round)
|
|
793
|
+
*/
|
|
794
|
+
addTurn(xoxId: number): number;
|
|
795
|
+
getTotalTurns(xoxId: number): number;
|
|
796
|
+
/**
|
|
797
|
+
* Summarize a batch of conversation messages into an episodic memory entry.
|
|
798
|
+
* Uses LLM to extract topic + summary.
|
|
799
|
+
*/
|
|
800
|
+
recordEpisode(xoxId: number, config: ModelConfig, messages: Array<{
|
|
801
|
+
role: string;
|
|
802
|
+
content: string;
|
|
803
|
+
}>): Promise<EpisodicEntry | null>;
|
|
804
|
+
/**
|
|
805
|
+
* Get recent episodes for prompt injection
|
|
806
|
+
*/
|
|
807
|
+
getRecentEpisodes(xoxId: number, count?: number): EpisodicEntry[];
|
|
808
|
+
/**
|
|
809
|
+
* Search episodes by keyword (simple substring match on topic + summary)
|
|
810
|
+
*/
|
|
811
|
+
searchEpisodes(xoxId: number, keyword: string, count?: number): EpisodicEntry[];
|
|
812
|
+
/**
|
|
813
|
+
* Clear all episodic memory (keeps totalTurns for maturity continuity)
|
|
814
|
+
*/
|
|
815
|
+
clearEpisodes(xoxId: number): void;
|
|
816
|
+
/**
|
|
817
|
+
* Delete memory file entirely
|
|
818
|
+
*/
|
|
819
|
+
deleteMemory(xoxId: number): void;
|
|
820
|
+
getStats(xoxId: number): {
|
|
821
|
+
totalTurns: number;
|
|
822
|
+
episodeCount: number;
|
|
823
|
+
updatedAt: number;
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
interface GroupChatMember {
|
|
828
|
+
xoxId: number;
|
|
829
|
+
nickname: string;
|
|
830
|
+
}
|
|
831
|
+
interface GroupChatMessage {
|
|
832
|
+
msgId: string;
|
|
833
|
+
speakerId: number;
|
|
834
|
+
speakerName: string;
|
|
835
|
+
content: string;
|
|
836
|
+
timestamp: number;
|
|
837
|
+
}
|
|
838
|
+
interface GroupChatSession {
|
|
839
|
+
sessionId: string;
|
|
840
|
+
name: string;
|
|
841
|
+
members: GroupChatMember[];
|
|
842
|
+
topic: string | null;
|
|
843
|
+
mode: 'observer' | 'participant';
|
|
844
|
+
messages: GroupChatMessage[];
|
|
845
|
+
createdAt: number;
|
|
846
|
+
lastActiveAt: number;
|
|
847
|
+
}
|
|
848
|
+
/**
|
|
849
|
+
* 群聊会话持久化存储。
|
|
850
|
+
*
|
|
851
|
+
* 通过 IStorage 抽象底层文件系统,替代原 hchuanz-pocket-helper 中
|
|
852
|
+
* `app.getPath('userData')` + `fs` 的直接调用。
|
|
853
|
+
*/
|
|
854
|
+
declare class GroupChatStore {
|
|
855
|
+
private storage;
|
|
856
|
+
private logger;
|
|
857
|
+
constructor(storage: IStorage, logger: ILogger);
|
|
858
|
+
private ensureDir;
|
|
859
|
+
saveSession(session: GroupChatSession): void;
|
|
860
|
+
getSession(sessionId: string): GroupChatSession | null;
|
|
861
|
+
listSessions(): GroupChatSession[];
|
|
862
|
+
deleteSession(sessionId: string): void;
|
|
863
|
+
/**
|
|
864
|
+
* Append a message to a session (read → push → write back)
|
|
865
|
+
*/
|
|
866
|
+
appendMessage(sessionId: string, msg: GroupChatMessage): void;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* 翻牌数据缓存服务。
|
|
871
|
+
*
|
|
872
|
+
* 通过 IStorage + IConfigStore 抽象底层持久化,替代原 hchuanz-pocket-helper 中
|
|
873
|
+
* `app.getPath('userData')` + `fs` + `storeService` 的直接调用。
|
|
874
|
+
*/
|
|
875
|
+
declare class FlipCacheService {
|
|
876
|
+
private storage;
|
|
877
|
+
private logger;
|
|
878
|
+
private configStore;
|
|
879
|
+
constructor(storage: IStorage, logger: ILogger, configStore: IConfigStore);
|
|
880
|
+
/** 计算仪表盘数据(纯逻辑) */
|
|
881
|
+
static calcDashboard(records: Array<{
|
|
882
|
+
status?: number;
|
|
883
|
+
cost?: number;
|
|
884
|
+
}>): DashboardInfo;
|
|
885
|
+
/** 按偶像分组(纯逻辑) */
|
|
886
|
+
static groupDataById(records: Array<{
|
|
887
|
+
answerId?: string;
|
|
888
|
+
cost?: number;
|
|
889
|
+
answerType?: number;
|
|
890
|
+
answerTime?: string;
|
|
891
|
+
qtime?: string;
|
|
892
|
+
type?: number;
|
|
893
|
+
baseUserInfo?: {
|
|
894
|
+
userId?: number;
|
|
895
|
+
nickname?: string;
|
|
896
|
+
};
|
|
897
|
+
}>): Record<string, FlipCardGroup>;
|
|
898
|
+
private writeCache;
|
|
899
|
+
/** 从旧版 storeService 迁移数据 */
|
|
900
|
+
private migrateFromLegacy;
|
|
901
|
+
get(userId: string): FlipUserCache | null;
|
|
902
|
+
set(cache: FlipUserCache): void;
|
|
903
|
+
clear(userId: string): void;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/** Thrown when Pocket API returns 401004 (auth expired) */
|
|
907
|
+
declare class PocketAuthExpiredError extends Error {
|
|
908
|
+
constructor();
|
|
909
|
+
}
|
|
910
|
+
/**
|
|
911
|
+
* Pocket48 API HTTP 客户端。
|
|
912
|
+
*
|
|
913
|
+
* 负责签名头构造、请求发送、auth 过期检测。
|
|
914
|
+
* 通过 IAuthExpiredHandler 回调通知宿主(替代原 ant-design-vue message/router 依赖)。
|
|
915
|
+
*/
|
|
916
|
+
declare class PocketClient {
|
|
917
|
+
private baseUrl;
|
|
918
|
+
private appInfo;
|
|
919
|
+
private pa;
|
|
920
|
+
private authExpiredHandler?;
|
|
921
|
+
private lastAuthWarnAt;
|
|
922
|
+
private lastKickAt;
|
|
923
|
+
constructor(baseUrl: string, appInfo: string, pa: string, authExpiredHandler?: IAuthExpiredHandler | undefined);
|
|
924
|
+
/** 登录态过期的单一出口:防抖调用 authExpiredHandler + 抛错 */
|
|
925
|
+
kickToLogin(): void;
|
|
926
|
+
/** 检查响应是否 auth 过期 */
|
|
927
|
+
checkAuthExpired(res: PocketApiResponse): void;
|
|
928
|
+
private buildSignedHeaders;
|
|
929
|
+
private buildPlainHeaders;
|
|
930
|
+
request<T = unknown>(path: string, data: unknown, token?: string, signed?: boolean): Promise<PocketApiResponse<T>>;
|
|
931
|
+
/** 登录前接口调用(不签名,不检测 auth 过期) */
|
|
932
|
+
requestBeforeLogin<T = unknown>(path: string, data: unknown): Promise<PocketApiResponse<T>>;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
/**
|
|
936
|
+
* Build a digital mirror by analyzing flip records with LLM
|
|
937
|
+
*/
|
|
938
|
+
interface RoomMessageEntry {
|
|
939
|
+
msgId: string;
|
|
940
|
+
msgTime: number;
|
|
941
|
+
text: string;
|
|
942
|
+
}
|
|
943
|
+
declare function buildMirror(xoxId: number, userId: string, config: ModelConfig, params: {
|
|
944
|
+
logger: ILogger;
|
|
945
|
+
llmClient: ILlmClient;
|
|
946
|
+
flipDataSource: IFlipDataSource;
|
|
947
|
+
mirrorStore: MirrorStore;
|
|
948
|
+
mirrorIndex: MirrorIndex;
|
|
949
|
+
xoxNickname?: string;
|
|
950
|
+
startTimeMs?: number;
|
|
951
|
+
endTimeMs?: number;
|
|
952
|
+
deepAnalysis?: boolean;
|
|
953
|
+
roomMessages?: RoomMessageEntry[];
|
|
954
|
+
}): Promise<{
|
|
955
|
+
ok: boolean;
|
|
956
|
+
message: string;
|
|
957
|
+
profile?: MirrorProfile;
|
|
958
|
+
}>;
|
|
959
|
+
|
|
960
|
+
/**
|
|
961
|
+
* Chat with a digital mirror using streaming + RAG + episodic memory.
|
|
962
|
+
*
|
|
963
|
+
* 重构要点:
|
|
964
|
+
* - ModelConfig 由调用方传入,不再从 storeService + safeStorage 读取
|
|
965
|
+
* - 所有依赖通过参数注入
|
|
966
|
+
*/
|
|
967
|
+
declare function chat(xoxId: number, userId: string, message: string, sessionId: string | null, config: ModelConfig, params: {
|
|
968
|
+
logger: ILogger;
|
|
969
|
+
llmClient: ILlmClient;
|
|
970
|
+
mirrorStore: MirrorStore;
|
|
971
|
+
mirrorIndex: MirrorIndex;
|
|
972
|
+
mirrorMemory: MirrorMemory;
|
|
973
|
+
}, onChunk: (content: string, isDone: boolean, newSessionId: string) => void, modelOverride?: string): Promise<void>;
|
|
974
|
+
/**
|
|
975
|
+
* Save assistant message to session (called after streaming is complete)
|
|
976
|
+
*/
|
|
977
|
+
declare function saveAssistantMessage(sessionId: string, userId: string, content: string, mirrorStore: MirrorStore): void;
|
|
978
|
+
/**
|
|
979
|
+
* Clear chat memory for a session
|
|
980
|
+
*/
|
|
981
|
+
declare function clearChatMemory(sessionId: string, userId: string, mirrorStore: MirrorStore): void;
|
|
982
|
+
|
|
983
|
+
type GrowthPhase = 'chatting' | 'reflecting' | 'updating';
|
|
984
|
+
interface GrowthResult {
|
|
985
|
+
ok: boolean;
|
|
986
|
+
message: string;
|
|
987
|
+
updated: boolean;
|
|
988
|
+
changes?: string[];
|
|
989
|
+
newPersona?: MirrorPersona;
|
|
990
|
+
}
|
|
991
|
+
/**
|
|
992
|
+
* Check whether auto-growth should be triggered for this mirror
|
|
993
|
+
*/
|
|
994
|
+
declare function shouldTriggerGrowth(xoxId: number, userId: string, mirrorStore: MirrorStore, mirrorMemory: MirrorMemory): boolean;
|
|
995
|
+
/**
|
|
996
|
+
* Run the growth state machine:
|
|
997
|
+
* chatting → reflecting (LLM review) → updating (merge persona) → chatting
|
|
998
|
+
*/
|
|
999
|
+
declare function triggerGrowth(xoxId: number, userId: string, config: ModelConfig, params: {
|
|
1000
|
+
logger: ILogger;
|
|
1001
|
+
llmClient: ILlmClient;
|
|
1002
|
+
mirrorStore: MirrorStore;
|
|
1003
|
+
mirrorMemory: MirrorMemory;
|
|
1004
|
+
}, force?: boolean): Promise<GrowthResult>;
|
|
1005
|
+
/**
|
|
1006
|
+
* Rollback to previous persona
|
|
1007
|
+
*/
|
|
1008
|
+
declare function rollbackPersona(xoxId: number, userId: string, mirrorStore: MirrorStore): {
|
|
1009
|
+
ok: boolean;
|
|
1010
|
+
message: string;
|
|
1011
|
+
};
|
|
1012
|
+
/**
|
|
1013
|
+
* Clear all memory of a mirror: episodic memory + chat sessions (keeps persona)
|
|
1014
|
+
*/
|
|
1015
|
+
declare function clearMirrorMemory(xoxId: number, userId: string, mirrorStore: MirrorStore, mirrorMemory: MirrorMemory): {
|
|
1016
|
+
ok: boolean;
|
|
1017
|
+
message: string;
|
|
1018
|
+
};
|
|
1019
|
+
|
|
1020
|
+
/**
|
|
1021
|
+
* Digital mirror configuration — dual-mode presets
|
|
1022
|
+
*
|
|
1023
|
+
* Model assignment:
|
|
1024
|
+
* Mirror generation → DeepSeek-V4-Pro (1M context, 1.6T/49B MoE)
|
|
1025
|
+
* Chat → Qwen3.6-35B-A3B (262K context, MoE)
|
|
1026
|
+
*
|
|
1027
|
+
* Token estimation (per flip record):
|
|
1028
|
+
* Fan ≤200 chars + Idol ≤500 chars = ≤700 chars ≈ 350 tokens
|
|
1029
|
+
*
|
|
1030
|
+
* All limits are tunable here. To adjust, edit the numbers below
|
|
1031
|
+
* and restart; no code changes needed.
|
|
1032
|
+
*/
|
|
1033
|
+
/**
|
|
1034
|
+
* Context budget reference:
|
|
1035
|
+
* Economy: ~280K tokens (800×350) — 28% of V4-Pro 1M window
|
|
1036
|
+
* Performance: ~700K tokens (2000×350) — 70% of V4-Pro 1M window
|
|
1037
|
+
*/
|
|
1038
|
+
declare const MIRROR_PRESETS: Record<MirrorMode, MirrorConfig>;
|
|
1039
|
+
/** Resolve effective config for a given mode, with optional user overrides */
|
|
1040
|
+
declare function getMirrorConfig(mode?: MirrorMode, overrides?: {
|
|
1041
|
+
analysisTemperature?: number;
|
|
1042
|
+
chatTemperature?: number;
|
|
1043
|
+
}): MirrorConfig;
|
|
1044
|
+
|
|
1045
|
+
/**
|
|
1046
|
+
* Platform-level built-in tools available to all agents.
|
|
1047
|
+
*
|
|
1048
|
+
* 重构要点:
|
|
1049
|
+
* - `flipCacheService` → 参数注入 `IFlipDataSource`
|
|
1050
|
+
* - `fs.readFileSync` → Node 内置 `fs`(平台工具 readFile 设计如此)
|
|
1051
|
+
*/
|
|
1052
|
+
declare function createPlatformTools(flipDataSource: IFlipDataSource): RegisteredTool[];
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* Mirror-specific tools available to the mirror agent.
|
|
1056
|
+
*
|
|
1057
|
+
* 重构要点:
|
|
1058
|
+
* - `mirrorStore` 模块单例 → 参数注入 MirrorStore 实例
|
|
1059
|
+
*/
|
|
1060
|
+
declare function createMirrorTools(mirrorStore: MirrorStore): RegisteredTool[];
|
|
1061
|
+
|
|
1062
|
+
/**
|
|
1063
|
+
* Pocket48 在线 API 工具集。
|
|
1064
|
+
*
|
|
1065
|
+
* 包装 pocket-core 的 Pocket48 API 模块为 MCP 工具,支持:
|
|
1066
|
+
* - 短信验证码 + Token 双路径登录
|
|
1067
|
+
* - 用户信息查询
|
|
1068
|
+
* - 成员/队伍查询与搜索
|
|
1069
|
+
* - 房间消息查询
|
|
1070
|
+
* - 翻牌数据同步、搜索、发送、历史
|
|
1071
|
+
*/
|
|
1072
|
+
declare function createPocketTools(params: {
|
|
1073
|
+
pocketClient: PocketClient;
|
|
1074
|
+
configStore: IConfigStore;
|
|
1075
|
+
flipDataSource: IFlipDataSource;
|
|
1076
|
+
logger: ILogger;
|
|
1077
|
+
}): RegisteredTool[];
|
|
1078
|
+
|
|
1079
|
+
declare function sendVerificationCode(client: PocketClient, phone: string): Promise<void>;
|
|
1080
|
+
declare function loginWithCode(client: PocketClient, phone: string, code: string): Promise<Record<string, unknown>>;
|
|
1081
|
+
/** 未读消息数。GET body 传空对象。返回 content: { notice, user, atme, comment } */
|
|
1082
|
+
declare function getUnreadMessageNum(client: PocketClient, token: string): Promise<PocketApiResponse<{
|
|
1083
|
+
notice: number;
|
|
1084
|
+
user: number;
|
|
1085
|
+
atme: number;
|
|
1086
|
+
comment: number;
|
|
1087
|
+
}>>;
|
|
1088
|
+
declare function loginWithToken(client: PocketClient, token: string): Promise<{
|
|
1089
|
+
[x: string]: unknown;
|
|
1090
|
+
} | null>;
|
|
1091
|
+
declare function normalizePocketUser(raw: Record<string, unknown>, token: string, phone?: string): PocketUser;
|
|
1092
|
+
|
|
1093
|
+
declare const pocketUser_getUnreadMessageNum: typeof getUnreadMessageNum;
|
|
1094
|
+
declare const pocketUser_loginWithCode: typeof loginWithCode;
|
|
1095
|
+
declare const pocketUser_loginWithToken: typeof loginWithToken;
|
|
1096
|
+
declare const pocketUser_normalizePocketUser: typeof normalizePocketUser;
|
|
1097
|
+
declare const pocketUser_sendVerificationCode: typeof sendVerificationCode;
|
|
1098
|
+
declare namespace pocketUser {
|
|
1099
|
+
export { pocketUser_getUnreadMessageNum as getUnreadMessageNum, pocketUser_loginWithCode as loginWithCode, pocketUser_loginWithToken as loginWithToken, pocketUser_normalizePocketUser as normalizePocketUser, pocketUser_sendVerificationCode as sendVerificationCode };
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
declare function syncFlips(client: PocketClient, token: string, userId: string, flipDataSource: IFlipDataSource, logger: ILogger, mode?: FlipSyncMode, onProgress?: (count: number) => void): Promise<{
|
|
1103
|
+
allUserData: FlipRecord[];
|
|
1104
|
+
dashboardInfo: DashboardInfo | null;
|
|
1105
|
+
}>;
|
|
1106
|
+
declare function getAllFlips(client: PocketClient, token: string, userId: string, flipDataSource: IFlipDataSource, logger: ILogger): Promise<{
|
|
1107
|
+
allUserData: FlipRecord[];
|
|
1108
|
+
dashboardInfo: DashboardInfo | null;
|
|
1109
|
+
}>;
|
|
1110
|
+
declare function getDataSourcePage(searchParams: FlipSearchParams, flipDataSource: IFlipDataSource, userId: string): Promise<{
|
|
1111
|
+
data: FlipRecord[];
|
|
1112
|
+
total: number;
|
|
1113
|
+
}>;
|
|
1114
|
+
declare function sendFlip(client: PocketClient, params: FlipSendParams, token: string): Promise<boolean>;
|
|
1115
|
+
interface FlipHistoryPage {
|
|
1116
|
+
records: FlipRecord[];
|
|
1117
|
+
hasMore: boolean;
|
|
1118
|
+
}
|
|
1119
|
+
/**
|
|
1120
|
+
* 查询指定成员的翻牌历史(对话样式展示用)。
|
|
1121
|
+
* 分页:beginLimit 从 10 起,每次 +limit;content 可能是数组或含 flipCompleteList/answerList/list 的对象。
|
|
1122
|
+
*/
|
|
1123
|
+
declare function getMemberFlipHistory(client: PocketClient, token: string, memberId: string | number, beginLimit?: number, limit?: number): Promise<FlipHistoryPage>;
|
|
1124
|
+
|
|
1125
|
+
type pocketFlip_FlipHistoryPage = FlipHistoryPage;
|
|
1126
|
+
declare const pocketFlip_getAllFlips: typeof getAllFlips;
|
|
1127
|
+
declare const pocketFlip_getDataSourcePage: typeof getDataSourcePage;
|
|
1128
|
+
declare const pocketFlip_getMemberFlipHistory: typeof getMemberFlipHistory;
|
|
1129
|
+
declare const pocketFlip_sendFlip: typeof sendFlip;
|
|
1130
|
+
declare const pocketFlip_syncFlips: typeof syncFlips;
|
|
1131
|
+
declare namespace pocketFlip {
|
|
1132
|
+
export { type pocketFlip_FlipHistoryPage as FlipHistoryPage, pocketFlip_getAllFlips as getAllFlips, pocketFlip_getDataSourcePage as getDataSourcePage, pocketFlip_getMemberFlipHistory as getMemberFlipHistory, pocketFlip_sendFlip as sendFlip, pocketFlip_syncFlips as syncFlips };
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
/**
|
|
1136
|
+
* 获取网易云信 IM 登录凭证(accid/pwd),用于登 NIM 长连接(房间消息实时推送)。
|
|
1137
|
+
*
|
|
1138
|
+
* 来源:POST /im/api/v1/im/userinfo(无 body),服务端按 token 下发。
|
|
1139
|
+
* 完整 URL = https://pocketapi.48.cn/im/api/v1/im/userinfo。
|
|
1140
|
+
*
|
|
1141
|
+
* 注意:accid/pwd ≠ HTTP token。前者是网易云信 IM 的账号/密码,后者是 Pocket48 业务 token。
|
|
1142
|
+
*/
|
|
1143
|
+
declare function getImUserInfo(client: PocketClient, token: string): Promise<ImUserInfo | null>;
|
|
1144
|
+
|
|
1145
|
+
declare const pocketIm_getImUserInfo: typeof getImUserInfo;
|
|
1146
|
+
declare namespace pocketIm {
|
|
1147
|
+
export { pocketIm_getImUserInfo as getImUserInfo };
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
declare function getTeamListInfo(client: PocketClient, token: string): Promise<{
|
|
1151
|
+
serverTabList: Array<{
|
|
1152
|
+
tabId: number;
|
|
1153
|
+
tabName: string;
|
|
1154
|
+
}>;
|
|
1155
|
+
} | undefined>;
|
|
1156
|
+
declare function getMemberListByTab(client: PocketClient, token: string, tabId: number): Promise<{
|
|
1157
|
+
serverApiList: Array<Record<string, unknown>>;
|
|
1158
|
+
} | undefined>;
|
|
1159
|
+
declare function fetchMemberList(client: PocketClient, token: string): Promise<MemberInfo[]>;
|
|
1160
|
+
declare function getMemberFlipPriceInfo(client: PocketClient, token: string, memberId: string): Promise<MemberFlipInfo>;
|
|
1161
|
+
|
|
1162
|
+
declare const pocketMember_fetchMemberList: typeof fetchMemberList;
|
|
1163
|
+
declare const pocketMember_getMemberFlipPriceInfo: typeof getMemberFlipPriceInfo;
|
|
1164
|
+
declare const pocketMember_getMemberListByTab: typeof getMemberListByTab;
|
|
1165
|
+
declare const pocketMember_getTeamListInfo: typeof getTeamListInfo;
|
|
1166
|
+
declare namespace pocketMember {
|
|
1167
|
+
export { pocketMember_fetchMemberList as fetchMemberList, pocketMember_getMemberFlipPriceInfo as getMemberFlipPriceInfo, pocketMember_getMemberListByTab as getMemberListByTab, pocketMember_getTeamListInfo as getTeamListInfo };
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
/** 通过成员 starId 跳转到主房间,拿到 channelId */
|
|
1171
|
+
declare function getRoomChannelByStar(client: PocketClient, token: string, starId: number): Promise<RoomJumpResult>;
|
|
1172
|
+
/** 获取房间基础信息 */
|
|
1173
|
+
declare function getRoomInfo(client: PocketClient, token: string, channelId: number): Promise<RoomChannelInfo | null>;
|
|
1174
|
+
/**
|
|
1175
|
+
* 分页拉取房间消息。
|
|
1176
|
+
* nextTime=0 拉最新一页;之后带上次的 nextTime 拉更早的消息。
|
|
1177
|
+
* 接口返回的消息为倒序(最新在前),此处统一转成正序(最旧在前)。
|
|
1178
|
+
*/
|
|
1179
|
+
declare function getRoomMessages(client: PocketClient, token: string, serverId: number, channelId: number, nextTime: number): Promise<RoomMessagePage>;
|
|
1180
|
+
|
|
1181
|
+
declare const pocketRoom_getRoomChannelByStar: typeof getRoomChannelByStar;
|
|
1182
|
+
declare const pocketRoom_getRoomInfo: typeof getRoomInfo;
|
|
1183
|
+
declare const pocketRoom_getRoomMessages: typeof getRoomMessages;
|
|
1184
|
+
declare namespace pocketRoom {
|
|
1185
|
+
export { pocketRoom_getRoomChannelByStar as getRoomChannelByStar, pocketRoom_getRoomInfo as getRoomInfo, pocketRoom_getRoomMessages as getRoomMessages };
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
interface AgentLoopOptions {
|
|
1189
|
+
config: ModelConfig;
|
|
1190
|
+
systemPrompt: string;
|
|
1191
|
+
userMessage: string;
|
|
1192
|
+
history?: ChatMessage[];
|
|
1193
|
+
maxIterations?: number;
|
|
1194
|
+
model?: string;
|
|
1195
|
+
onChunk?: (chunk: string) => void;
|
|
1196
|
+
onToolCall?: (name: string, args: Record<string, unknown>) => void;
|
|
1197
|
+
context: ToolContext;
|
|
1198
|
+
llmClient: ILlmClient;
|
|
1199
|
+
toolRegistry: ToolRegistry;
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Non-streaming agent loop: LLM <-> tool calling
|
|
1203
|
+
*/
|
|
1204
|
+
declare function agentLoop(options: AgentLoopOptions): Promise<string>;
|
|
1205
|
+
/**
|
|
1206
|
+
* Streaming agent loop with tool calling
|
|
1207
|
+
*/
|
|
1208
|
+
declare function agentLoopStream(options: AgentLoopOptions): Promise<void>;
|
|
1209
|
+
|
|
1210
|
+
/**
|
|
1211
|
+
* 组合根:core 对运行时依赖的完整声明。
|
|
1212
|
+
*
|
|
1213
|
+
* Electron 侧(hchuanz-pocket-helper)用自己的适配器(ElectronStorage/
|
|
1214
|
+
* ElectronSecureStorage/ElectronIpcStreamSink)组装;MCP/CLI 用 adapters/ 下的
|
|
1215
|
+
* Node 参考实现。core 本身不 import 任何框架。
|
|
1216
|
+
*/
|
|
1217
|
+
interface CoreDependencies {
|
|
1218
|
+
logger: ILogger;
|
|
1219
|
+
storage: IStorage;
|
|
1220
|
+
secureStorage: ISecureStorage;
|
|
1221
|
+
configStore: IConfigStore;
|
|
1222
|
+
flipDataSource: IFlipDataSource;
|
|
1223
|
+
llmClient: ILlmClient;
|
|
1224
|
+
/** 流式聊天输出;Electron 用 IPC,MCP 用回调 */
|
|
1225
|
+
chatStreamSink?: IChatStreamSink;
|
|
1226
|
+
/** 事件推送;Electron 用 webContents,MCP 用空实现 */
|
|
1227
|
+
eventSink?: IEventSink;
|
|
1228
|
+
/** 认证过期回调 */
|
|
1229
|
+
authExpiredHandler?: IAuthExpiredHandler;
|
|
1230
|
+
}
|
|
1231
|
+
/**
|
|
1232
|
+
* 面向外部的高层 API。
|
|
1233
|
+
*/
|
|
1234
|
+
interface PocketCore {
|
|
1235
|
+
deps: CoreDependencies;
|
|
1236
|
+
toolRegistry: ToolRegistry;
|
|
1237
|
+
pocketClient: PocketClient;
|
|
1238
|
+
mirrorStore: MirrorStore;
|
|
1239
|
+
flipCacheService: FlipCacheService;
|
|
1240
|
+
groupChatStore: GroupChatStore;
|
|
1241
|
+
mirrorIndex: MirrorIndex;
|
|
1242
|
+
mirrorMemory: MirrorMemory;
|
|
1243
|
+
buildMirror: typeof buildMirror;
|
|
1244
|
+
/** 镜像聊天 */
|
|
1245
|
+
mirrorChat: typeof chat;
|
|
1246
|
+
/** 保存助手回复到 session */
|
|
1247
|
+
mirrorSaveAssistantMessage: typeof saveAssistantMessage;
|
|
1248
|
+
/** 清除聊天记忆 */
|
|
1249
|
+
mirrorClearChatMemory: typeof clearChatMemory;
|
|
1250
|
+
/** 触发人格成长 */
|
|
1251
|
+
mirrorTriggerGrowth: typeof triggerGrowth;
|
|
1252
|
+
/** 检测是否需要触发成长 */
|
|
1253
|
+
mirrorShouldTriggerGrowth: typeof shouldTriggerGrowth;
|
|
1254
|
+
/** 回退人格 */
|
|
1255
|
+
mirrorRollbackPersona: typeof rollbackPersona;
|
|
1256
|
+
/** 清除镜像记忆 */
|
|
1257
|
+
mirrorClearMemory: typeof clearMirrorMemory;
|
|
1258
|
+
getMirrorConfig: typeof getMirrorConfig;
|
|
1259
|
+
createPlatformTools: () => ReturnType<typeof createPlatformTools>;
|
|
1260
|
+
createMirrorTools: () => ReturnType<typeof createMirrorTools>;
|
|
1261
|
+
createPocketTools: () => ReturnType<typeof createPocketTools>;
|
|
1262
|
+
pocketUser: typeof pocketUser;
|
|
1263
|
+
pocketFlip: typeof pocketFlip;
|
|
1264
|
+
pocketIm: typeof pocketIm;
|
|
1265
|
+
pocketMember: typeof pocketMember;
|
|
1266
|
+
pocketRoom: typeof pocketRoom;
|
|
1267
|
+
agentLoop: typeof agentLoop;
|
|
1268
|
+
agentLoopStream: typeof agentLoopStream;
|
|
1269
|
+
}
|
|
1270
|
+
/**
|
|
1271
|
+
* 创建 PocketCore 实例,组装所有业务模块。
|
|
1272
|
+
*/
|
|
1273
|
+
declare function createPocketCore(deps: CoreDependencies): PocketCore;
|
|
1274
|
+
|
|
1275
|
+
declare const PRESET_PROVIDERS: Record<string, {
|
|
1276
|
+
label: string;
|
|
1277
|
+
baseUrl: string;
|
|
1278
|
+
}>;
|
|
1279
|
+
declare const PRESET_MODELS: {
|
|
1280
|
+
chat: {
|
|
1281
|
+
id: string;
|
|
1282
|
+
label: string;
|
|
1283
|
+
desc: string;
|
|
1284
|
+
}[];
|
|
1285
|
+
reasoning: {
|
|
1286
|
+
id: string;
|
|
1287
|
+
label: string;
|
|
1288
|
+
desc: string;
|
|
1289
|
+
}[];
|
|
1290
|
+
embedding: {
|
|
1291
|
+
id: string;
|
|
1292
|
+
label: string;
|
|
1293
|
+
desc: string;
|
|
1294
|
+
}[];
|
|
1295
|
+
};
|
|
1296
|
+
declare function defaultModelConfig(): ModelConfig;
|
|
1297
|
+
|
|
1298
|
+
/**
|
|
1299
|
+
* Build the "inner monologue" prompt for a mirror to evaluate whether it wants to speak.
|
|
1300
|
+
* Uses lightweight model, expects JSON output.
|
|
1301
|
+
*/
|
|
1302
|
+
declare function buildInnerMonologuePrompt(profile: MirrorProfile, lastMessages: Array<{
|
|
1303
|
+
speakerId: number;
|
|
1304
|
+
speakerName: string;
|
|
1305
|
+
content: string;
|
|
1306
|
+
}>, topic: string | null): string;
|
|
1307
|
+
/**
|
|
1308
|
+
* Build the speech prompt for a mirror to generate its group chat reply.
|
|
1309
|
+
* Uses full persona + group context.
|
|
1310
|
+
*/
|
|
1311
|
+
declare function buildSpeakPrompt(profile: MirrorProfile, params: {
|
|
1312
|
+
name: string;
|
|
1313
|
+
topic: string | null;
|
|
1314
|
+
otherMembers: string;
|
|
1315
|
+
lastMessages: Array<{
|
|
1316
|
+
speakerName: string;
|
|
1317
|
+
content: string;
|
|
1318
|
+
}>;
|
|
1319
|
+
}): string;
|
|
1320
|
+
|
|
1321
|
+
interface SpeakDecision {
|
|
1322
|
+
xoxId: number;
|
|
1323
|
+
shouldSpeak: boolean;
|
|
1324
|
+
urgency: number;
|
|
1325
|
+
trigger: string;
|
|
1326
|
+
}
|
|
1327
|
+
interface GroupChatMessageEvent {
|
|
1328
|
+
sessionId: string;
|
|
1329
|
+
msgId: string;
|
|
1330
|
+
speakerId: number;
|
|
1331
|
+
speakerName: string;
|
|
1332
|
+
content: string;
|
|
1333
|
+
isDone: boolean;
|
|
1334
|
+
roundDone: boolean;
|
|
1335
|
+
}
|
|
1336
|
+
interface GroupChatDeps {
|
|
1337
|
+
logger: ILogger;
|
|
1338
|
+
llmClient: ILlmClient;
|
|
1339
|
+
mirrorStore: MirrorStore;
|
|
1340
|
+
groupChatStore: GroupChatStore;
|
|
1341
|
+
config: ModelConfig;
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1344
|
+
* Run a full round of group chat: evaluate → select → generate → push.
|
|
1345
|
+
*
|
|
1346
|
+
* @param session - The current group chat session (mutated: messages appended)
|
|
1347
|
+
* @param onEvent - Callback to push events to frontend
|
|
1348
|
+
* @returns Array of new messages generated this round
|
|
1349
|
+
*/
|
|
1350
|
+
declare function runRound(deps: GroupChatDeps, session: GroupChatSession, userId: string, onEvent: (event: GroupChatMessageEvent) => void): Promise<GroupChatMessage[]>;
|
|
1351
|
+
|
|
1352
|
+
export { AVA_BASE_URL, type AgentLoopOptions, CallbackStreamSink, type ChatCompletionChunk, type ChatCompletionOptions, type ChatCompletionResult, type ChatMessage, type ChatSession, ConsoleLogger, type CoreDependencies, type DashboardInfo, type EpisodicEntry, type FlipCacheMeta, FlipCacheService, type FlipCardGroup, type FlipHistoryPage, type FlipRecord, type FlipRecordVector, type FlipSearchParams, type FlipSendParams, type FlipSyncMode, type FlipUserCache, type GroupChatDeps, type GroupChatMember, type GroupChatMessage, type GroupChatMessageEvent, type GroupChatSession, GroupChatStore, type GrowthEvent, type GrowthPhase, type GrowthResult, type IAuthExpiredHandler, type IChatStreamSink, type IConfigStore, type IEventSink, type IFlipDataSource, type ILlmClient, type ILogger, type ISecureStorage, type IStorage, type ImUserInfo, type LegacyFlipReader, MIRROR_PRESETS, type MemberFlipCustom, type MemberFlipInfo, type MemberInfo, type MemberSearchParams, MemoryConfigStore, MemoryFlipDataSource, type MirrorConfig, MirrorIndex, MirrorMemory, type MirrorMode, type MirrorPersona, type MirrorProfile, type MirrorRecentActivity, type MirrorRelationship, MirrorStore, type ModelConfig, NodeJsonConfigStore, NodeJsonFileStorage, NodeJsonFlipDataSource, NoopEventSink, NoopLogger, OpenAICompatibleClient, POCKET_API_BASE, POCKET_APP_INFO, POCKET_PA, POCKET_USER_AGENT, PRESET_MODELS, PRESET_PROVIDERS, PlainTextSecureStorage, type PocketApiResponse, PocketAuthExpiredError, PocketClient, type PocketCore, type PocketUser, type RegisteredTool, type RoomChannelInfo, type RoomGiftInfo, type RoomJumpResult, type RoomLiveInfo, type RoomMessage, type RoomMessageEntry, type RoomMessagePage, type RoomMessageSender, type RoomReplyInfo, SESSION_EXPIRE_MS, type SearchHit, type SpeakDecision, type ToolContext, type ToolDefinition, ToolRegistry, agentLoop, agentLoopStream, buildInnerMonologuePrompt, buildMirror, buildSpeakPrompt, chat, clearChatMemory, clearMirrorMemory, createMirrorTools, createPlatformTools, createPocketCore, createPocketTools, defaultModelConfig, fetchMemberList, getAllFlips, getDataSourcePage, getImUserInfo, getMemberFlipHistory, getMemberFlipPriceInfo, getMemberListByTab, getMirrorConfig, getRoomChannelByStar, getRoomInfo, getRoomMessages, getTeamListInfo, getUnreadMessageNum, loginWithCode, loginWithToken, normalizePersona, normalizePocketUser, rollbackPersona, runRound, saveAssistantMessage, sendFlip, sendVerificationCode, shouldTriggerGrowth, syncFlips, triggerGrowth };
|