dsh-qqchat 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.
Files changed (89) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +276 -0
  3. package/README.md +211 -0
  4. package/client-src/plugin.cts +15 -0
  5. package/client-src/settings.cts +216 -0
  6. package/client-src/shared.cts +104 -0
  7. package/client-src/workspace.cts +164 -0
  8. package/cordis.patch.yml +7 -0
  9. package/docs/ARCHITECTURE.en.md +346 -0
  10. package/docs/ARCHITECTURE.md +411 -0
  11. package/docs/DEVELOPMENT.md +69 -0
  12. package/docs/MEDIA_AND_QUOTES.md +644 -0
  13. package/docs/MEMORY.md +99 -0
  14. package/docs/MEMORY_CONTEXT.md +254 -0
  15. package/docs/QUOTES.md +355 -0
  16. package/docs/README.md +22 -0
  17. package/docs/SECURITY.md +62 -0
  18. package/docs/STREAMING.md +347 -0
  19. package/docs/assets//346/211/253/347/240/201/351/223/276/346/216/245.jpg +0 -0
  20. package/docs/assets//347/276/244/350/201/212/347/225/214/351/235/242.jpg +0 -0
  21. package/docs/assets//350/256/260/345/277/206/347/263/273/347/273/237.jpg +0 -0
  22. package/docs/assets//350/256/276/347/275/256/347/225/214/351/235/242.jpg +0 -0
  23. package/docs/devlog.md +24 -0
  24. package/lib/client.js +433 -0
  25. package/lib/commands/dispatch.d.ts +16 -0
  26. package/lib/commands/dispatch.js +48 -0
  27. package/lib/config.d.ts +3 -0
  28. package/lib/config.js +63 -0
  29. package/lib/gateway/api.d.ts +30 -0
  30. package/lib/gateway/api.js +202 -0
  31. package/lib/gateway/auth.d.ts +35 -0
  32. package/lib/gateway/auth.js +80 -0
  33. package/lib/gateway/crypto.d.ts +2 -0
  34. package/lib/gateway/crypto.js +17 -0
  35. package/lib/gateway/gateway.d.ts +32 -0
  36. package/lib/gateway/gateway.js +219 -0
  37. package/lib/gateway/normalize.d.ts +6 -0
  38. package/lib/gateway/normalize.js +248 -0
  39. package/lib/index.d.ts +14 -0
  40. package/lib/index.js +35 -0
  41. package/lib/media/image-tool.d.ts +4 -0
  42. package/lib/media/image-tool.js +62 -0
  43. package/lib/media/media-tools.d.ts +3 -0
  44. package/lib/media/media-tools.js +68 -0
  45. package/lib/media/store.d.ts +14 -0
  46. package/lib/media/store.js +176 -0
  47. package/lib/session/agent-bridge.d.ts +56 -0
  48. package/lib/session/agent-bridge.js +613 -0
  49. package/lib/session/memory-snapshot.d.ts +23 -0
  50. package/lib/session/memory-snapshot.js +27 -0
  51. package/lib/session/runtime.d.ts +41 -0
  52. package/lib/session/runtime.js +395 -0
  53. package/lib/shared/augmentations.d.ts +40 -0
  54. package/lib/shared/augmentations.js +1 -0
  55. package/lib/shared/logging.d.ts +14 -0
  56. package/lib/shared/logging.js +41 -0
  57. package/lib/storage/db.d.ts +82 -0
  58. package/lib/storage/db.js +669 -0
  59. package/lib/storage/memory.d.ts +50 -0
  60. package/lib/storage/memory.js +566 -0
  61. package/lib/transport/rpc.d.ts +18 -0
  62. package/lib/transport/rpc.js +318 -0
  63. package/lib/types.d.ts +416 -0
  64. package/lib/types.js +1 -0
  65. package/package.json +115 -0
  66. package/scripts/wrap-client.mjs +20 -0
  67. package/src/commands/dispatch.ts +75 -0
  68. package/src/config.ts +70 -0
  69. package/src/gateway/api.ts +260 -0
  70. package/src/gateway/auth.ts +99 -0
  71. package/src/gateway/crypto.ts +16 -0
  72. package/src/gateway/gateway.ts +207 -0
  73. package/src/gateway/normalize.ts +236 -0
  74. package/src/index.ts +46 -0
  75. package/src/media/image-tool.ts +62 -0
  76. package/src/media/media-tools.ts +66 -0
  77. package/src/media/store.ts +157 -0
  78. package/src/session/agent-bridge.ts +624 -0
  79. package/src/session/memory-snapshot.ts +41 -0
  80. package/src/session/runtime.ts +368 -0
  81. package/src/shared/augmentations.ts +45 -0
  82. package/src/shared/logging.ts +36 -0
  83. package/src/storage/db.ts +760 -0
  84. package/src/storage/memory.ts +581 -0
  85. package/src/transport/rpc.ts +316 -0
  86. package/src/types.ts +456 -0
  87. package/tsconfig.build.json +12 -0
  88. package/tsconfig.client.json +14 -0
  89. package/tsconfig.json +23 -0
package/src/types.ts ADDED
@@ -0,0 +1,456 @@
1
+ import type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'
2
+
3
+ export type ChatType = 'c2c' | 'group'
4
+ export type MessageDirection = 'inbound' | 'outbound'
5
+ export type MemoryScopeType = 'group' | 'member'
6
+ export type MemoryDocType = 'profile' | 'summary' | 'daily' | 'memory' | 'pattern'
7
+ export type ProfileEntryType = 'name' | 'address' | 'pronoun' | 'background' | 'preference' | 'note'
8
+
9
+ export interface ProfileEntry {
10
+ type: ProfileEntryType
11
+ text: string
12
+ ts: number
13
+ }
14
+
15
+ export interface DailyEntry {
16
+ date: string
17
+ note: string
18
+ }
19
+ export type ReplyFormat = 'smart' | 'markdown' | 'compat'
20
+ export type GroupReceiveMode = 'auto' | 'mention' | 'silent'
21
+ export type GatewayStatus = 'offline' | 'connecting' | 'online' | 'error'
22
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error'
23
+ export type QQMediaKind = 'image' | 'audio' | 'video' | 'voice' | 'file'
24
+
25
+ export interface QQAttachmentInput {
26
+ sourceUrl?: string
27
+ filename: string
28
+ contentType?: string
29
+ size?: number
30
+ width?: number
31
+ height?: number
32
+ durationMs?: number
33
+ platformFileId?: string
34
+ quoted?: boolean
35
+ kind?: QQMediaKind
36
+ attachmentId?: string
37
+ }
38
+
39
+ export interface QQQuoteInput {
40
+ messageId?: string
41
+ senderId?: string
42
+ senderName?: string
43
+ text: string
44
+ attachments: QQAttachmentInput[]
45
+ }
46
+
47
+ export interface StoredAttachmentSummary {
48
+ id: string
49
+ kind: QQMediaKind
50
+ filename: string
51
+ contentType?: string
52
+ sizeBytes: number
53
+ quoted: boolean
54
+ /** Platform file identity used to preserve one-to-one input mapping. */
55
+ sourceFileId?: string
56
+ /** Position in the original QQ attachment list; used only as a lossless fallback. */
57
+ sourceIndex?: number
58
+ localPath?: string
59
+ imageRef?: ImageAttachmentRef
60
+ }
61
+
62
+ export interface QQChatRuntimeSettings {
63
+ memoryEnabled: boolean
64
+ groupReceiveMode: GroupReceiveMode
65
+ groupReplyFormat: ReplyFormat
66
+ directReplyFormat: ReplyFormat
67
+ directStreamingEnabled: boolean
68
+ groupMembersCanUseTools: boolean
69
+ groupMembersCanReceiveMedia: boolean
70
+ groupMembersCanReadMedia: boolean
71
+ ownerUserId: string
72
+ }
73
+
74
+ export interface QQChatRuntimeSettingsPatch {
75
+ memoryEnabled?: boolean
76
+ groupReceiveMode?: GroupReceiveMode
77
+ groupReplyFormat?: ReplyFormat
78
+ directReplyFormat?: ReplyFormat
79
+ directStreamingEnabled?: boolean
80
+ groupMembersCanUseTools?: boolean
81
+ groupMembersCanReceiveMedia?: boolean
82
+ groupMembersCanReadMedia?: boolean
83
+ ownerUserId?: string
84
+ }
85
+
86
+ export interface PluginLogEntry {
87
+ id: number
88
+ time: number
89
+ level: LogLevel
90
+ message: string
91
+ }
92
+
93
+ export interface LoggerLike {
94
+ error?: (...args: unknown[]) => void
95
+ warn?: (...args: unknown[]) => void
96
+ info?: (...args: unknown[]) => void
97
+ debug?: (...args: unknown[]) => void
98
+ }
99
+
100
+ export interface QQChatConfigInput {
101
+ dataDir?: string
102
+ source?: string
103
+ sandbox?: boolean
104
+ agentPreset?: string
105
+ provider?: string
106
+ model?: string
107
+ maxTokens?: number
108
+ groupChatEnabled?: boolean
109
+ groupRequiresAt?: boolean
110
+ groupReadEnabled?: boolean
111
+ replyFormat?: ReplyFormat
112
+ recentGroupMessages?: number
113
+ reflectionIdleMs?: number
114
+ reflectionBatchSize?: number
115
+ reflectionMaxMessages?: number
116
+ memoryMaxTokens?: number
117
+ memoryCompressionMaxTokens?: number
118
+ }
119
+
120
+ export interface QQChatConfig {
121
+ readonly dataDir: string
122
+ readonly source: string
123
+ readonly sandbox: boolean
124
+ readonly agentPreset?: string
125
+ readonly provider?: string
126
+ readonly model?: string
127
+ readonly maxTokens?: number
128
+ readonly groupChatEnabled: boolean
129
+ readonly groupRequiresAt: boolean
130
+ readonly groupReadEnabled: boolean
131
+ readonly replyFormat: ReplyFormat
132
+ readonly recentGroupMessages: number
133
+ readonly reflectionIdleMs: number
134
+ readonly reflectionBatchSize: number
135
+ readonly reflectionMaxMessages: number
136
+ readonly memoryMaxTokens: number
137
+ readonly memoryCompressionMaxTokens: number
138
+ }
139
+
140
+ export interface AccountRow {
141
+ id: number
142
+ app_id: string
143
+ app_secret: string
144
+ bot_user_id: string | null
145
+ enabled: 0 | 1
146
+ sandbox: 0 | 1
147
+ gateway_status: GatewayStatus
148
+ gateway_last_error: string | null
149
+ created_at: number
150
+ updated_at: number
151
+ }
152
+
153
+ export interface PublicAccountRow extends Omit<AccountRow, 'app_secret'> {}
154
+
155
+ export interface AuthTaskRow {
156
+ task_id: string
157
+ aes_key: string
158
+ expires_at: number
159
+ }
160
+
161
+ export interface GroupRow {
162
+ id: number
163
+ account_id: number
164
+ platform_group_id: string
165
+ name: string | null
166
+ enabled: 0 | 1
167
+ read_enabled: 0 | 1
168
+ dsh_session_id: string | null
169
+ created_at: number
170
+ updated_at: number
171
+ }
172
+
173
+ export interface GroupListRow extends GroupRow {
174
+ last_message_at: number | null
175
+ member_count: number
176
+ message_count: number
177
+ }
178
+
179
+ export interface DirectChatListRow extends MemberRow {
180
+ last_message_at: number | null
181
+ message_count: number
182
+ }
183
+
184
+ export interface ChatTargetRow {
185
+ chatType: ChatType
186
+ rowId: number
187
+ accountId: number
188
+ platformId: string
189
+ displayName: string
190
+ dshSessionId: string | null
191
+ lastMessageAt: number | null
192
+ messageCount: number
193
+ }
194
+
195
+ export interface GroupDefaults {
196
+ name?: string
197
+ enabled?: boolean
198
+ readEnabled?: boolean
199
+ }
200
+
201
+ export interface GroupPatch {
202
+ name?: string
203
+ enabled?: boolean
204
+ readEnabled?: boolean
205
+ }
206
+
207
+ export interface MemberRow {
208
+ id: number
209
+ account_id: number
210
+ platform_user_id: string
211
+ display_name: string | null
212
+ dsh_session_id: string | null
213
+ first_seen_at: number
214
+ last_seen_at: number
215
+ }
216
+
217
+ export interface GroupMemberRow {
218
+ id: number
219
+ platform_user_id: string
220
+ global_display_name: string | null
221
+ display_name: string | null
222
+ first_seen_at: number
223
+ last_seen_at: number
224
+ aliases_json: string | null
225
+ nicknames_json: string | null
226
+ message_count: number
227
+ }
228
+
229
+ export interface MessageRow {
230
+ id: number
231
+ account_id: number
232
+ platform_message_id: string | null
233
+ chat_type: ChatType
234
+ group_id: number | null
235
+ member_id: number | null
236
+ direction: MessageDirection
237
+ content: string
238
+ quoted_text: string | null
239
+ mentioned: 0 | 1
240
+ created_at: number
241
+ raw_json: string | null
242
+ attachments_json: string | null
243
+ quote_json: string | null
244
+ platform_user_id?: string | null
245
+ display_name?: string | null
246
+ }
247
+
248
+ export interface InsertMessageInput {
249
+ accountId: number
250
+ platformMessageId?: string
251
+ chatType: ChatType
252
+ groupId?: number
253
+ memberId?: number
254
+ direction: MessageDirection
255
+ content: string
256
+ quotedText?: string
257
+ mentioned?: boolean
258
+ createdAt?: number
259
+ raw?: unknown
260
+ attachments?: StoredAttachmentSummary[]
261
+ quote?: QQQuoteInput
262
+ }
263
+
264
+ export interface ReflectionStateRow {
265
+ group_id: number
266
+ last_message_id: number
267
+ last_reflected_at: number | null
268
+ }
269
+
270
+ export interface OutboxRow {
271
+ id: number
272
+ account_id: number
273
+ chat_type: ChatType
274
+ target_id: string
275
+ content: string
276
+ status: 'pending' | 'sent' | 'failed'
277
+ scheduled_at: number
278
+ sent_at: number | null
279
+ error: string | null
280
+ }
281
+
282
+ export type MemoryDocuments = Partial<Record<MemoryDocType, string>>
283
+
284
+ export interface QQChatDisplayEvent {
285
+ messageId: string
286
+ chatType: ChatType
287
+ chatId: string
288
+ direction: MessageDirection
289
+ senderId: string
290
+ senderName: string
291
+ isOwner?: boolean
292
+ content: string
293
+ quotedText: string
294
+ mentioned: boolean
295
+ createdAt: number
296
+ sessionId?: string
297
+ attachments?: StoredAttachmentSummary[]
298
+ quote?: QQQuoteInput
299
+ }
300
+
301
+ export interface QQNormalizedMessage {
302
+ platform: 'qq'
303
+ accountId: number
304
+ chatType: ChatType
305
+ chatId: string
306
+ senderId: string
307
+ senderName: string
308
+ groupOpenid?: string
309
+ messageId: string
310
+ msgIdx?: string
311
+ refMsgIdx?: string
312
+ text: string
313
+ quotedText: string
314
+ attachments: QQAttachmentInput[]
315
+ quote?: QQQuoteInput
316
+ mentioned: boolean
317
+ botMentionId: string
318
+ raw: Record<string, unknown>
319
+ }
320
+
321
+ export interface QQQuoteIndexInput {
322
+ accountId: number
323
+ chatType: ChatType
324
+ chatId: string
325
+ msgIdx: string
326
+ platformMessageId?: string
327
+ senderId: string
328
+ senderName?: string
329
+ content: string
330
+ attachments: QQAttachmentInput[]
331
+ createdAt: number
332
+ expiresAt: number
333
+ }
334
+
335
+ export interface QQQuoteIndexRow extends QQQuoteIndexInput {
336
+ id: number
337
+ }
338
+
339
+ export interface QQAuthor {
340
+ user_openid?: string
341
+ member_openid?: string
342
+ id?: string
343
+ username?: string
344
+ nickname?: string
345
+ [key: string]: unknown
346
+ }
347
+
348
+ export interface QQMention {
349
+ bot?: boolean
350
+ is_you?: boolean
351
+ id?: string
352
+ user_openid?: string
353
+ member_openid?: string
354
+ openid?: string
355
+ [key: string]: unknown
356
+ }
357
+
358
+ export interface QQDispatchData extends Record<string, unknown> {
359
+ id?: string
360
+ content?: string
361
+ group_openid?: string
362
+ author?: QQAuthor
363
+ mentions?: QQMention[]
364
+ message_reference?: Record<string, unknown>
365
+ reference?: Record<string, unknown>
366
+ quote?: Record<string, unknown>
367
+ msg_elements?: Array<Record<string, unknown>>
368
+ message_scene?: { ext?: unknown[] }
369
+ attachments?: Array<Record<string, unknown>>
370
+ }
371
+
372
+ export interface QQAccessTokenPayload {
373
+ access_token?: string
374
+ expires_in?: number | string
375
+ [key: string]: unknown
376
+ }
377
+
378
+ export interface QQGatewayPayload {
379
+ url?: string
380
+ [key: string]: unknown
381
+ }
382
+
383
+ export interface QQBindCreatePayload {
384
+ retcode?: number
385
+ msg?: string
386
+ data?: { task_id?: string }
387
+ }
388
+
389
+ export interface QQBindPollPayload {
390
+ retcode?: number
391
+ msg?: string
392
+ data?: {
393
+ status?: number
394
+ bot_appid?: string | number
395
+ bot_encrypt_secret?: string
396
+ }
397
+ }
398
+
399
+ export interface QQGatewayFrame {
400
+ op: number
401
+ s?: number
402
+ t?: string
403
+ d?: Record<string, unknown> & {
404
+ heartbeat_interval?: number
405
+ session_id?: string
406
+ user?: { id?: string; openid?: string }
407
+ }
408
+ }
409
+
410
+ export interface QQSendOptions {
411
+ group?: boolean
412
+ messageId?: string | null
413
+ format?: ReplyFormat
414
+ }
415
+
416
+ export interface ModelRoute {
417
+ provider: string
418
+ model: string
419
+ sessionId?: string
420
+ }
421
+
422
+ export interface PendingReply {
423
+ text: string
424
+ onTextDelta?: (delta: string) => void
425
+ }
426
+
427
+ export interface ReflectionGroupUpdate {
428
+ profile?: unknown
429
+ summary?: unknown
430
+ daily?: unknown
431
+ memory?: unknown
432
+ }
433
+
434
+ export interface ReflectionMemberUpdate {
435
+ senderId?: unknown
436
+ profile?: unknown
437
+ pattern?: unknown
438
+ summary?: unknown
439
+ memory?: unknown
440
+ nicknames?: unknown
441
+ }
442
+
443
+ export interface ReflectionPayload {
444
+ group?: ReflectionGroupUpdate
445
+ members?: ReflectionMemberUpdate[]
446
+ }
447
+
448
+ export interface MemoryViewMember extends GroupMemberRow {
449
+ memory: MemoryDocuments
450
+ }
451
+
452
+ export interface MemoryView {
453
+ group: GroupRow
454
+ groupMemory: MemoryDocuments
455
+ members: MemoryViewMember[]
456
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "noEmit": false,
5
+ "rootDir": "./src",
6
+ "outDir": "./lib",
7
+ "declaration": true
8
+ },
9
+ "include": [
10
+ "src/**/*.ts"
11
+ ]
12
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "noEmit": false,
5
+ "module": "Node16",
6
+ "moduleResolution": "Node16",
7
+ "verbatimModuleSyntax": false,
8
+ "rootDir": "./client-src",
9
+ "outDir": "./.client-build",
10
+ "declaration": false,
11
+ "sourceMap": false
12
+ },
13
+ "include": ["client-src/**/*.cts"]
14
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2023",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "lib": ["ES2023", "DOM", "DOM.Iterable"],
7
+ "types": ["node"],
8
+ "strict": true,
9
+ "noUncheckedIndexedAccess": true,
10
+ "noImplicitOverride": true,
11
+ "useUnknownInCatchVariables": true,
12
+ "verbatimModuleSyntax": false,
13
+ "forceConsistentCasingInFileNames": true,
14
+ "skipLibCheck": true,
15
+ "noEmit": true
16
+ },
17
+ "include": [
18
+ "src/**/*.ts",
19
+ "client-src/**/*.cts",
20
+ "tests/**/*.ts",
21
+ "scripts/**/*.ts"
22
+ ]
23
+ }