@goodandready/dsh-messenger-gateway 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commands.js +3 -0
- package/lib/gateway.js +43 -1
- package/lib/index.js +2 -0
- package/lib/voice-prefs.js +3 -1
- package/package.json +8 -8
package/lib/commands.js
CHANGED
|
@@ -10,6 +10,9 @@ export const DEFAULT_TELEGRAM_COMMANDS = [
|
|
|
10
10
|
{ command: 'model', description: 'Показать или сменить модель' },
|
|
11
11
|
{ command: 'status', description: 'Статус шлюза' },
|
|
12
12
|
{ command: 'voice', description: 'Голосовые ответы: /voice on|off|status' },
|
|
13
|
+
{ command: 'tts', description: 'Озвучка в этом чате: /tts on|off|status' },
|
|
14
|
+
{ command: 'mute', description: 'Не присылать уведомления в этот чат' },
|
|
15
|
+
{ command: 'unmute', description: 'Вернуть уведомления в этот чат' },
|
|
13
16
|
]
|
|
14
17
|
|
|
15
18
|
export function normalizeTelegramCommands(commands) {
|
package/lib/gateway.js
CHANGED
|
@@ -62,8 +62,14 @@ export class Gateway {
|
|
|
62
62
|
const home = process.env.DSH_HOME || join(homedir(), '.dsh')
|
|
63
63
|
this.pairing = createPairingStore(join(home, 'messenger-gateway', 'pairing.json'))
|
|
64
64
|
this.voicePrefs = createVoicePrefs(join(home, 'messenger-gateway', 'voice-prefs.json'))
|
|
65
|
+
this.chatTts = createVoicePrefs(join(home, 'messenger-gateway', 'chat-tts.json'))
|
|
66
|
+
this.muted = createVoicePrefs(join(home, 'messenger-gateway', 'muted.json'))
|
|
67
|
+
this.stats = { sent: 0, errors: 0, startedAt: Date.now() }
|
|
65
68
|
}
|
|
66
69
|
|
|
70
|
+
isMuted(chatId) { return this.muted.get(chatId) === true }
|
|
71
|
+
setMuted(chatId, on) { return this.muted.set(chatId, on) }
|
|
72
|
+
|
|
67
73
|
baseUrl() {
|
|
68
74
|
const raw = String(this.config.internalBaseURL || '').trim()
|
|
69
75
|
return raw || 'http://127.0.0.1:3080'
|
|
@@ -130,6 +136,7 @@ export class Gateway {
|
|
|
130
136
|
await adapter.start()
|
|
131
137
|
this.adapterList.push(adapter)
|
|
132
138
|
this.adapters.set(adapter.name, adapter)
|
|
139
|
+
if (adapter.name === 'telegram') this.tgAdapter = adapter
|
|
133
140
|
this.ctx.logger?.info?.(`dsh-messenger-gateway: ${adapter.name} started`)
|
|
134
141
|
} catch (err) {
|
|
135
142
|
this.ctx.logger?.warn?.(`dsh-messenger-gateway: ${adapter.name}: ${err.message}`)
|
|
@@ -173,7 +180,9 @@ export class Gateway {
|
|
|
173
180
|
if (!adapter?.sendTo) throw new Error(`adapter ${resolved.platform} unavailable`)
|
|
174
181
|
try {
|
|
175
182
|
await adapter.sendTo(resolved.chatId, payload, { threadId: resolved.threadId })
|
|
183
|
+
this.stats.sent++
|
|
176
184
|
} catch (err) {
|
|
185
|
+
this.stats.errors++
|
|
177
186
|
if (isTopicGoneError(err)) {
|
|
178
187
|
this.logger?.warn?.(`messengerSend: topic gone for ${resolved.platform}:${resolved.chatId}:${resolved.threadId} — the chat/topic was deleted; skipping delivery`)
|
|
179
188
|
return
|
|
@@ -362,7 +371,12 @@ export class Gateway {
|
|
|
362
371
|
}
|
|
363
372
|
return reply('Активной сессии нет.')
|
|
364
373
|
}
|
|
365
|
-
if (cmd === '/whoami')
|
|
374
|
+
if (cmd === '/whoami') {
|
|
375
|
+
const lines = [`Ваш id: ${userId}`]
|
|
376
|
+
if (chatId) lines.push(`chatId: ${chatId}`)
|
|
377
|
+
if (threadId) lines.push(`threadId: ${threadId}`)
|
|
378
|
+
return reply(lines.join('\n'))
|
|
379
|
+
}
|
|
366
380
|
if (cmd === '/stop') {
|
|
367
381
|
const chat = this.chats.get(key)
|
|
368
382
|
if (chat?.turnActive || chat?.abort) {
|
|
@@ -386,6 +400,10 @@ export class Gateway {
|
|
|
386
400
|
? `home: chat ${home.chatId}${home.threadId ? ` topic ${home.threadId}` : ''}`
|
|
387
401
|
: 'home: не задан'
|
|
388
402
|
const pending = this.pairing.listPending().length
|
|
403
|
+
const up = Math.max(0, Math.round((Date.now() - this.stats.startedAt) / 1000))
|
|
404
|
+
const hh = String(Math.floor(up / 3600)).padStart(2, '0')
|
|
405
|
+
const mm = String(Math.floor((up % 3600) / 60)).padStart(2, '0')
|
|
406
|
+
const ss = String(up % 60).padStart(2, '0')
|
|
389
407
|
return reply([
|
|
390
408
|
'Messenger gateway',
|
|
391
409
|
`адаптеры: ${[...this.adapters.keys()].join(', ') || '(нет)'}`,
|
|
@@ -395,6 +413,10 @@ export class Gateway {
|
|
|
395
413
|
`pairing pending: ${pending}`,
|
|
396
414
|
`transport: ${this.tg().transport || 'poll'}`,
|
|
397
415
|
`sessionScope: ${this.config.agent?.sessionScope || 'user'}`,
|
|
416
|
+
`доставлено: ${this.stats.sent}`,
|
|
417
|
+
`ошибок: ${this.stats.errors}`,
|
|
418
|
+
`polling conflict: ${this.tgAdapter?.pollingConflict ? 'да' : 'нет'}`,
|
|
419
|
+
`uptime: ${hh}:${mm}:${ss}`,
|
|
398
420
|
].join('\n'))
|
|
399
421
|
}
|
|
400
422
|
if (cmd === '/model') {
|
|
@@ -466,6 +488,24 @@ export class Gateway {
|
|
|
466
488
|
const prefLine = pref === null ? 'не задан (/voice on|off)' : (pref ? 'on' : 'off')
|
|
467
489
|
return reply(`voiceMode=${mode}\nваш /voice: ${prefLine}\nglobal tts: ${this.config.tts?.enabled ? 'on' : 'off'}`)
|
|
468
490
|
}
|
|
491
|
+
if (cmd === '/tts') {
|
|
492
|
+
const sub = String(parts[1] || 'status').toLowerCase()
|
|
493
|
+
if (sub === 'on' || sub === 'off') {
|
|
494
|
+
this.chatTts.set(chatId, sub === 'on')
|
|
495
|
+
return reply(sub === 'on' ? 'Озвучка в этом чате: on' : 'Озвучка в этом чате: off')
|
|
496
|
+
}
|
|
497
|
+
const cur = this.chatTts.get(chatId)
|
|
498
|
+
const line = cur === null ? 'не задан (/tts on|off)' : (cur ? 'on' : 'off')
|
|
499
|
+
return reply(`Озвучка в этом чате: ${line}\nglobal tts: ${this.config.tts?.enabled ? 'on' : 'off'}`)
|
|
500
|
+
}
|
|
501
|
+
if (cmd === '/mute') {
|
|
502
|
+
this.setMuted(chatId, true)
|
|
503
|
+
return reply('Уведомления в этот чат: выключены (/unmute)')
|
|
504
|
+
}
|
|
505
|
+
if (cmd === '/unmute') {
|
|
506
|
+
this.setMuted(chatId, false)
|
|
507
|
+
return reply('Уведомления в этот чат: включены')
|
|
508
|
+
}
|
|
469
509
|
return reply(`Неизвестная команда ${cmd}. /help`)
|
|
470
510
|
}
|
|
471
511
|
|
|
@@ -674,11 +714,13 @@ export class Gateway {
|
|
|
674
714
|
await reply({ text: chunks[i] || undefined, files: i === 0 ? files : [] })
|
|
675
715
|
}
|
|
676
716
|
}
|
|
717
|
+
const chatTtsPref = this.chatTts.get(chat.target?.chatId)
|
|
677
718
|
const speak = shouldSpeakReply({
|
|
678
719
|
globalTts: Boolean(this.config.tts?.enabled),
|
|
679
720
|
voiceMode: this.tg().voiceMode || 'mirror',
|
|
680
721
|
inboundWasVoice: Boolean(inboundWasVoice),
|
|
681
722
|
userPref: this.voicePrefs.get(userId),
|
|
723
|
+
chatPref: chatTtsPref,
|
|
682
724
|
})
|
|
683
725
|
if (speak && !signal.aborted) {
|
|
684
726
|
const ttsText = prepareTtsText(answer, this.config.tts?.maxChars)
|
package/lib/index.js
CHANGED
|
@@ -244,6 +244,8 @@ export function apply(ctx, config) {
|
|
|
244
244
|
lines.push(`error: ${reason.error?.message || reason.error?.code || 'unknown'}`)
|
|
245
245
|
}
|
|
246
246
|
const homeName = cfg.home || 'default'
|
|
247
|
+
const home = gw.messenger.home?.() || null
|
|
248
|
+
if (home && gw.isMuted?.(home.chatId)) return
|
|
247
249
|
gw.messengerSend({ platform: 'telegram', home: homeName }, { text: lines.join('\n') })
|
|
248
250
|
.catch((e) => ctx.logger?.warn?.(`notify bridge: ${e.message}`))
|
|
249
251
|
}), 'dsh-messenger-gateway: notify bridge')
|
package/lib/voice-prefs.js
CHANGED
|
@@ -33,7 +33,9 @@ export function createVoicePrefs(filePath) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/** Decide whether to speak the reply. */
|
|
36
|
-
export function shouldSpeakReply({ globalTts, voiceMode, inboundWasVoice, userPref }) {
|
|
36
|
+
export function shouldSpeakReply({ globalTts, voiceMode, inboundWasVoice, userPref, chatPref }) {
|
|
37
|
+
if (chatPref === false) return false
|
|
38
|
+
if (chatPref === true) return true
|
|
37
39
|
if (globalTts) return true
|
|
38
40
|
if (userPref === true) return true
|
|
39
41
|
if (userPref === false) return false
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-messenger-gateway",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Telegram messenger bridge for DeepSeek Harness: sessions, steer, homes, inline asks, notify bridge, and optional TTS voice notes.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -52,14 +52,14 @@
|
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
55
|
-
"@deepseek-ai/dsh-agent": "^0.1.
|
|
56
|
-
"@deepseek-ai/dsh-agent-loop": "^0.1.
|
|
57
|
-
"@deepseek-ai/dsh-host-webserver": "^0.1.
|
|
58
|
-
"@deepseek-ai/dsh-llm": "^0.1.
|
|
59
|
-
"@deepseek-ai/dsh-session": "^0.1.
|
|
60
|
-
"@deepseek-ai/dsh-settings": "^0.1.
|
|
55
|
+
"@deepseek-ai/dsh-agent": "^0.1.1-rc.2",
|
|
56
|
+
"@deepseek-ai/dsh-agent-loop": "^0.1.1-rc.2",
|
|
57
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.2",
|
|
58
|
+
"@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
|
|
59
|
+
"@deepseek-ai/dsh-session": "^0.1.1-rc.2",
|
|
60
|
+
"@deepseek-ai/dsh-settings": "^0.1.1-rc.2",
|
|
61
61
|
"@deepseek-ai/schemastery": "^3.18.1",
|
|
62
|
-
"@deepseek-ai/dsh-tools": "^0.1.
|
|
62
|
+
"@deepseek-ai/dsh-tools": "^0.1.1-rc.2"
|
|
63
63
|
},
|
|
64
64
|
"publishConfig": {
|
|
65
65
|
"access": "public"
|