dsh-tg-bridge 1.2.9 → 1.2.10
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/bridge.mjs +3 -22
- package/immediate.mjs +56 -0
- package/package.json +3 -2
package/bridge.mjs
CHANGED
|
@@ -23,6 +23,7 @@ import net from 'node:net';
|
|
|
23
23
|
dns.setDefaultResultOrder('ipv4first');
|
|
24
24
|
net.setDefaultAutoSelectFamily(false);
|
|
25
25
|
import { noticeIsObsolete } from './queue-notice.mjs';
|
|
26
|
+
import { immediateKind } from './immediate.mjs';
|
|
26
27
|
import { handleControl, CONTROL_COMMANDS } from './control.mjs';
|
|
27
28
|
import { renderPrices } from './prices.mjs';
|
|
28
29
|
import { t, resolveLang } from './i18n.mjs';
|
|
@@ -474,33 +475,13 @@ function commandOf(text) {
|
|
|
474
475
|
return `/${match[1].toLowerCase().replace(/[.-]+/g, '')}`;
|
|
475
476
|
}
|
|
476
477
|
|
|
477
|
-
/**
|
|
478
|
-
* Commands that must run *now*, not behind the turn they are about.
|
|
479
|
-
*
|
|
480
|
-
* Everything in a topic used to be queued, so `/stop` waited for the very turn
|
|
481
|
-
* it was supposed to kill — on 2026-10-24 a 26-minute turn swallowed `/stop`
|
|
482
|
-
* and the person got "ход уже идёт" instead of an interruption. These few
|
|
483
|
-
* commands touch no turn state, so they can run concurrently with one.
|
|
484
|
-
*/
|
|
485
|
-
const IMMEDIATE_COMMANDS = new Set([
|
|
486
|
-
'stop',
|
|
487
|
-
'logs',
|
|
488
|
-
'status',
|
|
489
|
-
'help',
|
|
490
|
-
'doctor',
|
|
491
|
-
'restart',
|
|
492
|
-
]);
|
|
493
|
-
|
|
494
478
|
/** Canonical immediate command name for a message, or '' when it must queue. */
|
|
495
479
|
function immediateCommandOf(text) {
|
|
496
480
|
const trimmed = String(text ?? '').trim();
|
|
497
481
|
if (!trimmed.startsWith('/')) return '';
|
|
498
|
-
const head = trimmed.split(/\s+/)
|
|
482
|
+
const [head, ...rest] = trimmed.split(/\s+/);
|
|
499
483
|
const collapsed = commandOf(head).replace(/^\//, '');
|
|
500
|
-
|
|
501
|
-
return 'restart';
|
|
502
|
-
}
|
|
503
|
-
return IMMEDIATE_COMMANDS.has(collapsed) ? collapsed : '';
|
|
484
|
+
return immediateKind(collapsed, rest);
|
|
504
485
|
}
|
|
505
486
|
|
|
506
487
|
/**
|
package/immediate.mjs
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Which control commands may run while a turn is still working?
|
|
2
|
+
//
|
|
3
|
+
// Everything in a topic used to be queued, so `/stop` waited for the very turn
|
|
4
|
+
// it was supposed to kill. The rule here is not "important commands", it is
|
|
5
|
+
// "commands that neither read nor write the state of the running turn".
|
|
6
|
+
//
|
|
7
|
+
// Groups:
|
|
8
|
+
// * always immediate — read-only reports and turn control;
|
|
9
|
+
// * immediate only without arguments — the bare form reports, the form with
|
|
10
|
+
// an argument changes state (`/soul <text>`, `/lang en`);
|
|
11
|
+
// * `/plugins` without an action — the list; with add/remove/disable/enable
|
|
12
|
+
// it installs plugins, which must queue like any other mutation;
|
|
13
|
+
// * everything else queues, because it changes the session the turn is using
|
|
14
|
+
// (`/model`, `/new`, `/resume`, `/cd`, `/send`, `/seed`, `/plugin`).
|
|
15
|
+
|
|
16
|
+
const PLUGIN_ACTIONS = new Set(['add', 'remove', 'disable', 'enable']);
|
|
17
|
+
|
|
18
|
+
const ALWAYS = new Set([
|
|
19
|
+
// Turn control.
|
|
20
|
+
'stop',
|
|
21
|
+
'restart',
|
|
22
|
+
// Reports: they read profiles, sessions, skills and the price table, but
|
|
23
|
+
// touch neither the queue nor the session of the running turn.
|
|
24
|
+
'status',
|
|
25
|
+
'logs',
|
|
26
|
+
'help',
|
|
27
|
+
'doctor',
|
|
28
|
+
'models',
|
|
29
|
+
'sessions',
|
|
30
|
+
'skills',
|
|
31
|
+
'prices',
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
const BARE_ONLY = new Set([
|
|
35
|
+
'soul', // `/soul` reads AGENTS.md, `/soul <text>` rewrites it
|
|
36
|
+
'lang', // `/lang` reports the current language, `/lang en` switches it
|
|
37
|
+
]);
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Canonical immediate command name, or '' when the message must queue.
|
|
41
|
+
* `name` is the command without the slash and without a bot mention,
|
|
42
|
+
* `args` is everything after it, already split.
|
|
43
|
+
*/
|
|
44
|
+
export function immediateKind(name, args = []) {
|
|
45
|
+
const command = String(name ?? '').toLowerCase();
|
|
46
|
+
if (command === 'apprestart' || command === 'apprestartconfirm' || command === 'restartconfirm') {
|
|
47
|
+
return 'restart';
|
|
48
|
+
}
|
|
49
|
+
if (ALWAYS.has(command)) return command;
|
|
50
|
+
if (command === 'plugins') {
|
|
51
|
+
const [action = ''] = args;
|
|
52
|
+
return PLUGIN_ACTIONS.has(String(action).toLowerCase()) ? '' : 'plugins';
|
|
53
|
+
}
|
|
54
|
+
if (BARE_ONLY.has(command) && args.length === 0) return command;
|
|
55
|
+
return '';
|
|
56
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-tg-bridge",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.10",
|
|
4
4
|
"description": "Telegram bridge for DeepSeek Harness: text, voice, photos and project-per-topic sessions without opening the desktop app",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "bridge.mjs",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"LICENSE",
|
|
46
46
|
"config.example.json",
|
|
47
47
|
"patches/",
|
|
48
|
-
"queue-notice.mjs"
|
|
48
|
+
"queue-notice.mjs",
|
|
49
|
+
"immediate.mjs"
|
|
49
50
|
]
|
|
50
51
|
}
|