dsh-telegram-bot 0.0.0-stage → 0.1.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/CREDITS.md +10 -0
- package/LICENSE +21 -0
- package/README.md +189 -2
- package/client.js +783 -0
- package/cordis.patch.yml +8 -0
- package/icon.svg +12 -0
- package/index.js +2924 -0
- package/locale/en.json +6 -0
- package/locale/ru.json +6 -0
- package/package.json +59 -4
package/CREDITS.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Credits
|
|
2
|
+
|
|
3
|
+
## telegramify-markdown
|
|
4
|
+
|
|
5
|
+
Markdown → Telegram MarkdownV2 conversion is provided by
|
|
6
|
+
[telegramify-markdown](https://github.com/skoropadas/telegramify-markdown),
|
|
7
|
+
licensed under the MIT License.
|
|
8
|
+
|
|
9
|
+
It is built on [Unified](https://github.com/unifiedjs/unified) and
|
|
10
|
+
[Remark](https://github.com/remarkjs/remark/).
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Boobaw
|
|
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/README.md
CHANGED
|
@@ -1,3 +1,190 @@
|
|
|
1
|
-
#
|
|
1
|
+
# dsh-telegram-bot
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Telegram bot for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness), configured from the Harness Web UI.
|
|
4
|
+
|
|
5
|
+
> Found a bug or have an idea? [Open an issue](https://github.com/Boobaw/dsh-telegram-bot/issues).
|
|
6
|
+
|
|
7
|
+
The bot connects to Telegram, enforces the allowlists, and bridges DSH agent sessions to Telegram **DM topics**. The **All** topic stays global; every DSH session gets its own topic. The assistant answer is the first message and streams in place as text arrives; the current reasoning block and a rolling tool-call list update after it, then both transient messages are deleted when the answer is ready. A separate **System** topic mirrors bot lifecycle notifications, which also appear in **All**.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Settings → Telegram** page in the Web UI.
|
|
12
|
+
- **Bot token**, stored through the credential seam and never written into the settings file. The credential reference is configurable with `tokenRef` (default `TELEGRAM_BOT_TOKEN`).
|
|
13
|
+
- **Allowed users** — Telegram user ids or `@usernames`.
|
|
14
|
+
- **Allowed chats** — Telegram chat ids or `@channelnames`; empty means private chats only.
|
|
15
|
+
- **Enable bot** toggle.
|
|
16
|
+
- **Restart bot** button — reapplies the saved settings and restarts long polling.
|
|
17
|
+
- **Plugins page** — the bundle page is informational and points to Settings → Telegram. The bundle switch above it is the plugin on/off control; turning it off unmounts the runtime and aborts polling.
|
|
18
|
+
- **Agent bridge** — an ordinary text message in a session topic starts a DSH agent turn in that session, with assistant text streamed back.
|
|
19
|
+
- **DM topics** — `/sessions` in **All** is the single place for DSH sessions: choose a workspace, then create a new session in it or open an existing one. The selected session continues in its own topic. Requires **Threaded mode** in @BotFather → Bot Settings.
|
|
20
|
+
- **All and System topics** — All is Telegram's default topic and the management hub; System receives bot lifecycle notifications, mirrored into All.
|
|
21
|
+
- **Thinking and tool calls** — reasoning deltas and tool calls are mirrored into the topic, with independent **Show model thinking** / **Show tool calls** switches. Thinking is a 10-line rolling window; the tool-call message shows the last ten calls.
|
|
22
|
+
- **Commands** — `/start`, `/help`, `/sessions`, `/stop`, `/status`, `/current`, `/menu`, `/rename`, `/last`, `/restart`, `/id`, `/ping`.
|
|
23
|
+
- **Approval prompts** — when a tool asks for approval, the session topic gets a styled prompt with **Deny** and **Allow** inline buttons; the decision resolves the exact pending request.
|
|
24
|
+
- **Session controls** — an inline 2×2 panel in each session topic: **Model** (Flash/Pro), **Effort** (off/low/high/max), **Mode** (permission preset), and **Context** (window, last request usage, and cache-hit percentage). Telegram reply keyboards are chat-wide, so the controls are a per-topic inline panel rather than a bottom keyboard.
|
|
25
|
+
- **Recovery** — `/last [n]` shows the latest assistant answer(s) from the bound session, useful after switching between Web and Telegram. `/rename <name>` changes the Telegram topic title; `/restart` restarts the Telegram runtime; `/menu` opens the inline session controls.
|
|
26
|
+
- **Language** — bot messages and the Telegram command menu default to English; a Settings selector switches them to Russian.
|
|
27
|
+
- **Formatting** — assistant Markdown (headings, bold, lists, code, links, tables) is converted to Telegram MarkdownV2.
|
|
28
|
+
- **Command hints** — the runtime publishes the list with `setMyCommands`, so Telegram shows the commands and descriptions when the user types `/`. The descriptions follow the selected Bot language; English is the default.
|
|
29
|
+
- English and Russian page copy; Russian is registered as an optional language pack.
|
|
30
|
+
|
|
31
|
+
## Install
|
|
32
|
+
|
|
33
|
+
From this checkout, run in the repository root:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
npx @deepseek-ai/dsh plugin --profile web add .
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
After publishing to npm:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
npx @deepseek-ai/dsh plugin --profile web add dsh-telegram-bot
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`dsh plugin add` installs the package and selects its bundle in `dsh.profile.bundles` when the package declares `dsh.bundle`. Restart `dsh web` if the running profile does not pick the new bundle up through HMR.
|
|
46
|
+
|
|
47
|
+
Then open **Settings → Telegram** (or **Plugins → Telegram Bot**) in the Web UI.
|
|
48
|
+
|
|
49
|
+
## Configure
|
|
50
|
+
|
|
51
|
+
| Field | Where it lives | Meaning |
|
|
52
|
+
| --- | --- | --- |
|
|
53
|
+
| Bot token | credential store | Token from [@BotFather](https://t.me/BotFather); write-only from the page |
|
|
54
|
+
| `tokenRef` | profile configuration | Credential/env name that holds the token; default `TELEGRAM_BOT_TOKEN` |
|
|
55
|
+
| `cwd` | profile configuration | Working directory for Telegram-created DSH sessions; default process cwd |
|
|
56
|
+
| `agentPreset` | profile configuration | Preset mounted for Telegram sessions when presets are available; default `standard` |
|
|
57
|
+
| Allowed users | profile configuration | Numeric Telegram user ids or `@usernames`; empty means nobody |
|
|
58
|
+
| Allowed chats | profile configuration | Numeric chat ids (groups are negative) or `@channelnames`; empty means private chats only |
|
|
59
|
+
| Show model thinking | profile configuration | Mirror reasoning deltas into a Thinking message |
|
|
60
|
+
| Show tool calls | profile configuration | Mirror tool names and arguments into the topic |
|
|
61
|
+
| Bot language | profile configuration | `en` (default) or `ru` for all Telegram bot messages |
|
|
62
|
+
| Enable bot | profile configuration | Whether the runtime polls Telegram while the profile runs |
|
|
63
|
+
| Restart | request field | Forces a fresh `getMe` + `getUpdates` cycle |
|
|
64
|
+
|
|
65
|
+
The token field reports only whether a token is configured. A token supplied by the process environment is reported as configured but cannot be overwritten from the page. Changing `tokenRef` points the runtime and the page at another credential; use it to run several bots from one host.
|
|
66
|
+
|
|
67
|
+
### First run
|
|
68
|
+
|
|
69
|
+
1. Create a bot with [@BotFather](https://t.me/BotFather) and save its token in **Settings → Telegram**.
|
|
70
|
+
2. In @BotFather open the bot's **Bot Settings → Threaded mode** and enable it. Without this, private-chat topics cannot be created.
|
|
71
|
+
3. Open the bot chat, tap the bot name and enable **Topics**. **All** is Telegram's default topic; the bot creates **System** for lifecycle notifications.
|
|
72
|
+
4. Send `/start` in **All**. With an empty user list the bot replies with your user id and chat id, plus the Threaded-mode reminder.
|
|
73
|
+
5. Add your user id to **Allowed users** and press **Save** (or **Restart bot**).
|
|
74
|
+
6. In **All** send `/sessions` to create a new session or pick an existing DSH session. The dialog continues in its own topic.
|
|
75
|
+
|
|
76
|
+
The runtime starts only when **Enable bot** is on, a token is configured, and the profile process is running. It logs connection and polling diagnostics with the `[telegram]` prefix. Runtime state is at `$DSH_HOME/telegram/status.json`, and the topic → session mapping is at `$DSH_HOME/telegram/state.json` (neither contains the token).
|
|
77
|
+
|
|
78
|
+
## Headless profile (no Web UI)
|
|
79
|
+
|
|
80
|
+
The bot does not need the Web server. A profile with `dsh-base` and this bundle polls Telegram on its own; the settings page simply is not available there.
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
mkdir -p ~/.dsh/profiles/tg
|
|
84
|
+
cd ~/.dsh/profiles/tg
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`~/.dsh/profiles/tg/package.json`:
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"name": "dsh-profile-tg",
|
|
92
|
+
"private": true,
|
|
93
|
+
"dependencies": { "dsh-telegram-bot": "^0.1.0" },
|
|
94
|
+
"dsh": {
|
|
95
|
+
"profile": {
|
|
96
|
+
"bundles": ["@deepseek-ai/dsh-base", "dsh-telegram-bot"]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`~/.dsh/profiles/tg/cordis.patch.yml`:
|
|
103
|
+
|
|
104
|
+
```yaml
|
|
105
|
+
- id: telegram-bot
|
|
106
|
+
name: dsh-telegram-bot
|
|
107
|
+
config:
|
|
108
|
+
enabled: true
|
|
109
|
+
allowedUsers: ["<user-id>"]
|
|
110
|
+
allowedChats: ["<chat-id>"]
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Install and run without Web:
|
|
114
|
+
|
|
115
|
+
```sh
|
|
116
|
+
cd ~/.dsh/profiles/tg
|
|
117
|
+
npm install
|
|
118
|
+
|
|
119
|
+
# Prefer the credential store; for a headless deployment the matching
|
|
120
|
+
# environment variable is the supported fallback.
|
|
121
|
+
printf 'TELEGRAM_BOT_TOKEN=%s\n' '<token>' >> ~/.dsh/.env
|
|
122
|
+
chmod 600 ~/.dsh/.env
|
|
123
|
+
|
|
124
|
+
npx @deepseek-ai/dsh --profile tg
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
No browser and no port are opened. `Ctrl+C` stops the process; `$DSH_HOME/telegram/status.json` shows the runtime state. Do not put the token in `cordis.patch.yml`.
|
|
128
|
+
|
|
129
|
+
## Plugins page
|
|
130
|
+
|
|
131
|
+
The bundle detail page in **Plugins** is a short informational panel:
|
|
132
|
+
|
|
133
|
+
- it points to **Settings → Telegram** for token, access lists, language and display options;
|
|
134
|
+
- it lists the manual configuration files for headless setups;
|
|
135
|
+
- it does not duplicate the settings controls.
|
|
136
|
+
|
|
137
|
+
The bundle switch above the panel is the plugin on/off control. **Settings → Telegram → Enable bot** is a soft pause that keeps the plugin loaded but stops polling.
|
|
138
|
+
|
|
139
|
+
## Security
|
|
140
|
+
|
|
141
|
+
- Approvals requested by Telegram-owned agents are answered in the session topic with **Deny / Allow**; unanswered prompts stay pending until the turn is cancelled or `/stop` is used.
|
|
142
|
+
- The token is a secret: it lives in the credential store, not in `cordis.patch.yml`.
|
|
143
|
+
- An empty user list answers only in private chats with the setup hint. Once the list is non-empty, unauthorized users are ignored.
|
|
144
|
+
- Group/channel chats require an explicit **Allowed chats** entry.
|
|
145
|
+
- A DSH plugin runs in-process with the Host. Install only packages whose source you trust.
|
|
146
|
+
- Do not run two pollers with the same bot token; Telegram answers `409 Conflict` and one of them stops.
|
|
147
|
+
|
|
148
|
+
## Develop
|
|
149
|
+
|
|
150
|
+
No build step is needed: `index.js` is the Host half and `client.js` is the browser bundle in the module-loader factory format.
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
npm install
|
|
154
|
+
node --check client.js
|
|
155
|
+
node --check index.js
|
|
156
|
+
node -e "import('./index.js').then((m) => console.log(m.name, Object.keys(m)))"
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Inspect the composed profile:
|
|
160
|
+
|
|
161
|
+
```sh
|
|
162
|
+
npx @deepseek-ai/dsh --profile web --dump-config
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Publish and claim the name
|
|
166
|
+
|
|
167
|
+
`dsh-telegram-bot` is an unscoped npm name. Publishing the package is what claims it; no other registry or catalog is required for DSH installation.
|
|
168
|
+
|
|
169
|
+
```sh
|
|
170
|
+
npm login
|
|
171
|
+
npm whoami
|
|
172
|
+
npm publish --dry-run
|
|
173
|
+
npm publish
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
A Git URL or tarball also works for DSH (`dsh plugin add github:you/dsh-telegram-bot`), but the npm package name is the identity used by `dsh plugin add`, Plugin Manager, and `npx`. Use the same name for the GitHub repository and add the `dsh-plugin` topic for discovery.
|
|
177
|
+
|
|
178
|
+
## Roadmap
|
|
179
|
+
|
|
180
|
+
1. File attachments and voice input.
|
|
181
|
+
2. Multiple chats and group/topic routing.
|
|
182
|
+
3. Richer tool-result summaries.
|
|
183
|
+
|
|
184
|
+
## License
|
|
185
|
+
|
|
186
|
+
MIT
|
|
187
|
+
|
|
188
|
+
## Credits
|
|
189
|
+
|
|
190
|
+
Markdown to Telegram formatting uses [telegramify-markdown](https://github.com/skoropadas/telegramify-markdown) (MIT).
|