create-openclaw-bot 5.7.10 → 5.8.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.
@@ -1,315 +1,313 @@
1
- // @ts-nocheck
2
- (function (root) {
3
- const OPENCLAW_NPM_SPEC = 'openclaw@2026.5.4';
4
- const OPENCLAW_RUNTIME_PACKAGES = 'grammy @grammyjs/runner @grammyjs/transformer-throttler @buape/carbon @larksuiteoapi/node-sdk @slack/web-api';
5
- const NINE_ROUTER_NPM_SPEC = '9router@latest';
6
- const NINE_ROUTER_PORT = 20128;
7
- const NINE_ROUTER_PROXY_API_KEY = 'sk-no-key';
8
- const NINE_ROUTER_API_BASE_URL = `http://localhost:${NINE_ROUTER_PORT}`;
9
- const NINE_ROUTER_DOCKER_API_BASE_URL = `http://9router:${NINE_ROUTER_PORT}`;
10
- const SUPPORTED_CODEX_MODELS = ['cx/gpt-5.4', 'cx/gpt-5.3-codex', 'cx/gpt-5.2', 'cx/gpt-5.4-mini'];
11
- const SMART_ROUTE_PROVIDER_MODELS = {
12
- codex: SUPPORTED_CODEX_MODELS,
13
- 'claude-code': ['cc/claude-opus-4-7', 'cc/claude-opus-4-6', 'cc/claude-sonnet-4-6', 'cc/claude-opus-4-5-20251101', 'cc/claude-sonnet-4-5-20250929', 'cc/claude-haiku-4-5-20251001'],
14
- github: ['gh/gpt-5.4', 'gh/gpt-5.3-codex', 'gh/gpt-5.2-codex', 'gh/gpt-5.2', 'gh/gpt-5.1-codex-max', 'gh/gpt-5.1-codex', 'gh/gpt-5.1-codex-mini', 'gh/gpt-5.1', 'gh/gpt-5-codex', 'gh/gpt-5', 'gh/gpt-4.1', 'gh/gpt-4o', 'gh/claude-opus-4.6', 'gh/claude-sonnet-4.6', 'gh/claude-sonnet-4.5', 'gh/claude-opus-4.5', 'gh/claude-haiku-4.5', 'gh/gemini-3-pro-preview', 'gh/gemini-3-flash-preview', 'gh/gemini-2.5-pro', 'gh/grok-code-fast-1'],
15
- cursor: ['cu/default', 'cu/claude-4.6-opus-max', 'cu/claude-4.6-sonnet-medium-thinking', 'cu/claude-4.5-opus-high-thinking', 'cu/claude-4.5-opus-high', 'cu/claude-4.5-sonnet-thinking', 'cu/claude-4.5-sonnet', 'cu/claude-4.5-haiku', 'cu/claude-4.5-opus', 'cu/gpt-5.3-codex', 'cu/gpt-5.2-codex', 'cu/gpt-5.2', 'cu/kimi-k2.5', 'cu/gemini-3-flash-preview'],
16
- kilo: ['kc/anthropic/claude-sonnet-4-20250514', 'kc/anthropic/claude-opus-4-20250514', 'kc/google/gemini-2.5-pro', 'kc/google/gemini-2.5-flash', 'kc/openai/gpt-4.1', 'kc/openai/o3', 'kc/deepseek/deepseek-chat', 'kc/deepseek/deepseek-reasoner'],
17
- cline: ['cl/anthropic/claude-opus-4.7', 'cl/anthropic/claude-sonnet-4.6', 'cl/anthropic/claude-opus-4.6', 'cl/openai/gpt-5.4', 'cl/openai/gpt-5.3-codex', 'cl/google/gemini-3.1-pro-preview', 'cl/google/gemini-3.1-flash-lite-preview', 'cl/kwaipilot/kat-coder-pro'],
18
- 'gemini-cli': ['gc/gemini-3-flash-preview', 'gc/gemini-3-pro-preview'],
19
- kiro: ['kr/claude-sonnet-4.5', 'kr/claude-haiku-4.5', 'kr/deepseek-3.2', 'kr/deepseek-3.1', 'kr/qwen3-coder-next', 'kr/glm-5', 'kr/MiniMax-M2.5'],
20
- 'kimi-coding': ['kmc/kimi-k2.5', 'kmc/kimi-k2.5-thinking', 'kmc/kimi-latest'],
21
- openai: ['openai/gpt-5.4', 'openai/gpt-5.4-mini', 'openai/gpt-5.2', 'openai/gpt-5.1', 'openai/gpt-5', 'openai/gpt-4o', 'openai/gpt-4.1', 'openai/o3', 'openai/o4-mini'],
22
- anthropic: ['anthropic/claude-sonnet-4-20250514', 'anthropic/claude-opus-4-20250514', 'anthropic/claude-3-5-sonnet-20241022'],
23
- gemini: ['gemini/gemini-3.1-pro-preview', 'gemini/gemini-3-flash-preview', 'gemini/gemini-2.5-pro', 'gemini/gemini-2.5-flash', 'gemini/gemini-2.5-flash-lite'],
24
- deepseek: ['deepseek/deepseek-chat', 'deepseek/deepseek-reasoner'],
25
- xai: ['xai/grok-4', 'xai/grok-4-fast-reasoning', 'xai/grok-code-fast-1', 'xai/grok-3'],
26
- mistral: ['mistral/mistral-large-latest', 'mistral/codestral-latest', 'mistral/mistral-medium-latest'],
27
- iflow: ['if/qwen3-coder-plus', 'if/qwen3-max', 'if/qwen3-vl-plus', 'if/qwen3-max-preview', 'if/qwen3-235b', 'if/qwen3-32b', 'if/kimi-k2', 'if/deepseek-v3.2', 'if/deepseek-v3.1', 'if/deepseek-v3', 'if/deepseek-r1', 'if/glm-4.7', 'if/iflow-rome-30ba3b'],
28
- qwen: ['qw/qwen3-coder-plus', 'qw/qwen3-coder-flash', 'qw/vision-model', 'qw/coder-model'],
29
- alicode: ['alicode/qwen3.5-plus', 'alicode/kimi-k2.5', 'alicode/glm-5', 'alicode/qwen3-coder-next', 'alicode/qwen3-coder-plus', 'alicode/glm-4.7'],
30
- groq: ['groq/llama-3.3-70b-versatile', 'groq/openai/gpt-oss-120b', 'groq/qwen/qwen3-32b'],
31
- cerebras: ['cerebras/gpt-oss-120b', 'cerebras/zai-glm-4.7', 'cerebras/qwen-3-32b'],
32
- glm: ['glm/glm-5.1', 'glm/glm-5', 'glm/glm-4.7'],
33
- 'glm-cn': ['glm-cn/glm-5.1', 'glm-cn/glm-5', 'glm-cn/glm-4.7', 'glm-cn/glm-4.6'],
34
- minimax: ['minimax/MiniMax-M2.7', 'minimax/MiniMax-M2.5', 'minimax/MiniMax-M2.1'],
35
- kimi: ['kimi/kimi-k2.5', 'kimi/kimi-k2.5-thinking', 'kimi/kimi-latest'],
36
- ollama: ['ollama/qwen3.5', 'ollama/kimi-k2.5', 'ollama/glm-5', 'ollama/minimax-m2.5', 'ollama/glm-4.7-flash', 'ollama/gpt-oss:120b'],
37
- };
38
- const SMART_ROUTE_PROVIDER_ORDER = ['openai', 'anthropic', 'claude-code', 'codex', 'cursor', 'github', 'cline', 'kimi', 'minimax', 'deepseek', 'glm', 'alicode', 'xai', 'mistral', 'kilo', 'kiro', 'iflow', 'qwen', 'gemini-cli', 'gemini', 'ollama'];
39
- const TELEGRAM_RELAY_PLUGIN_SPEC = 'openclaw-telegram-multibot-relay';
40
- const TELEGRAM_RELAY_PLUGIN_ID = 'telegram-multibot-relay';
41
- const TELEGRAM_SETUP_GUIDE_FILENAME = 'TELEGRAM-GROUP-SETUP.md';
42
-
43
- function buildRelayPluginInstallCommand(prefix = 'openclaw') {
44
- return `if [ ! -d "$OPENCLAW_STATE_DIR/extensions/${TELEGRAM_RELAY_PLUGIN_ID}" ]; then ${prefix} plugins install ${TELEGRAM_RELAY_PLUGIN_SPEC} 2>/dev/null || true; fi`;
45
- }
46
-
47
- function buildRelayPluginInstallCommandWin(prefix = 'openclaw') {
48
- return `if not exist ".openclaw\\extensions\\${TELEGRAM_RELAY_PLUGIN_ID}\\" ${prefix} plugins install ${TELEGRAM_RELAY_PLUGIN_SPEC} || exit /b 0`;
49
- }
50
-
51
- function buildTelegramPostInstallChecklist(options = {}) {
52
- const {
53
- isVi = true,
54
- bots = [],
55
- groupId = '',
56
- relayPluginSpec = TELEGRAM_RELAY_PLUGIN_SPEC,
57
- includeTokenPreview = false,
58
- } = options;
59
- const botList = bots.map((bot, idx) => {
60
- const name = bot?.name || `Bot ${idx + 1}`;
61
- if (includeTokenPreview) {
62
- return `- **${name}** — token: ${String(bot?.token || '').slice(0, 10)}...`;
63
- }
64
- return `- **${name}**`;
65
- }).join('\n');
66
-
67
- if (isVi) {
68
- return `# Telegram Group Setup Guide
69
-
70
- Bot da duoc cai dat. Thuc hien cac buoc sau de hoat dong trong group.
71
-
72
- ## Group ID
73
- - ${groupId ? `Group ID: ${groupId}` : 'Chua nhap Group ID - bot se hoat dong o moi group.'}
74
-
75
- ## Danh sach bot
76
- ${botList}
77
-
78
- ---
79
-
80
- ## Buoc 1 -- Tat Privacy Mode tren BotFather (bat buoc, lam truoc)
81
-
82
- Mac dinh bot chi doc tin nhan bat dau bang /. Phai tat Privacy Mode thi bot moi doc duoc tat ca tin nhan trong group.
83
-
84
- Lam lan luot cho TUNG BOT:
85
- 1. Mo Telegram, tim @BotFather
86
- 2. Gui: /mybots
87
- 3. Chon bot can sua
88
- 4. Chon: Bot Settings
89
- 5. Chon: Group Privacy
90
- 6. Chon: Turn off
91
- 7. BotFather se bao: "Privacy mode is disabled for ..."
92
-
93
- !!! QUAN TRONG: Phai lam buoc nay TRUOC khi add bot vao group. Neu bot da o trong group roi thi phai Remove bot ra, sau do Add lai.
94
-
95
- ## Buoc 2 -- Add bot vao group
96
-
97
- Sau khi tat Privacy Mode cho ALL bot:
98
- 1. Mo group Telegram cua ban
99
- 2. Vao Settings -> Members -> Add Members
100
- 3. Tim ten tung bot theo username (VD: @TenCuaBot) va add vao
101
- 4. Sau khi add, vao Settings -> Administrators
102
- 5. Promote tung bot len Admin (can quyen phan hoi, co the de mac dinh)
103
-
104
- Lay username that cua bot: vao @BotFather -> /mybots -> chon bot -> username la chu sau @.
105
-
106
- ## Buoc 3 -- Lay Group ID (neu chua co)
107
-
108
- 1. Them @userinfobot vao group nhu admin
109
- 2. Go /start hoac forward bat ky tin nhan trong group cho @userinfobot
110
- 3. Bot tra ve Chat ID bat dau bang -100...
111
- 4. Dat gia tri do vao TELEGRAM_GROUP_ID trong file .env
112
-
113
- ## Buoc 4 -- Cai plugin (neu chua cai duoc tu dong)
114
-
115
- Neu trong qua trinh setup bao loi cai plugin, sau khi bot dang chay hay chay:
116
-
117
- openclaw plugins install ${relayPluginSpec}
118
-
119
- ## Buoc 5 -- Test
120
-
121
- 1. Gui tin nhan trong group, mention bot: @TenCuaBot xin chao
122
- 2. Bot se phan hoi
123
- 3. Neu khong phan hoi: kiem tra lai Buoc 1 (Privacy Mode) va Buoc 2 (add lai sau khi tat privacy)
124
-
125
- ---
126
- *Generated by OpenClaw Setup*
127
- `;
128
- }
129
-
130
- return `# Telegram Group Setup Guide
131
-
132
- Bots are installed. Complete the steps below to activate them in a group.
133
-
134
- ## Group ID
135
- - ${groupId ? `Group ID: ${groupId}` : 'No Group ID - bots will respond in any group.'}
136
-
137
- ## Bot list
138
- ${botList}
139
-
140
- ---
141
-
142
- ## Step 1 -- Disable Privacy Mode on BotFather (required, do this first)
143
-
144
- By default bots only read messages starting with /. You must disable Privacy Mode so bots can read all group messages.
145
-
146
- Do this for EACH BOT:
147
- 1. Open Telegram, find @BotFather
148
- 2. Send: /mybots
149
- 3. Select the bot
150
- 4. Choose: Bot Settings
151
- 5. Choose: Group Privacy
152
- 6. Choose: Turn off
153
- 7. BotFather confirms: "Privacy mode is disabled for ..."
154
-
155
- !!! IMPORTANT: Do this BEFORE adding the bot to the group. If the bot is already in the group, remove it first then re-add it.
156
-
157
- ## Step 2 -- Add bots to the group
158
-
159
- After disabling Privacy Mode for ALL bots:
160
- 1. Open your Telegram group
161
- 2. Go to Settings -> Members -> Add Members
162
- 3. Search each bot by username (e.g. @YourBotUsername) and add it
163
- 4. Go to Settings -> Administrators
164
- 5. Promote each bot to Admin
165
-
166
- To get each bot's real username: open @BotFather -> /mybots -> select bot -> username after @.
167
-
168
- ## Step 3 -- Get Group ID (if not already set)
169
-
170
- 1. Add @userinfobot to the group as admin
171
- 2. Send /start or forward any group message to @userinfobot
172
- 3. It returns a Chat ID starting with -100...
173
- 4. Set that value as TELEGRAM_GROUP_ID in your .env file
174
-
175
- ## Step 4 -- Install plugin (if auto-install failed)
176
-
177
- If setup reported a plugin install error, run this after the bot is running:
178
-
179
- openclaw plugins install ${relayPluginSpec}
180
-
181
- ## Step 5 -- Test
182
-
183
- 1. Send a message in the group mentioning the bot: @YourBotUsername hello
184
- 2. The bot should respond
185
- 3. No response? Re-check Step 1 (Privacy Mode) and Step 2 (re-add bot after disabling privacy)
186
-
187
- ---
188
- *Generated by OpenClaw Setup*
189
- `;
190
- }
191
-
192
- function buildAuthProfilesJson(options = {}) {
193
- const {
194
- providerKey = '',
195
- provider = {},
196
- apiKey = '',
197
- isProxy = false,
198
- isLocal = false,
199
- localUrl = 'http://ollama:11434',
200
- proxyKey = 'sk-no-key',
201
- } = options;
202
-
203
- if (isLocal) {
204
- return {
205
- version: 1,
206
- profiles: {
207
- 'ollama:default': {
208
- provider: 'ollama',
209
- type: 'api_key',
210
- key: 'ollama-local',
211
- url: localUrl,
212
- },
213
- },
214
- order: { ollama: ['ollama:default'] },
215
- };
216
- }
217
-
218
- const authProviderName = isProxy ? '9router' : providerKey;
219
- const authProfileId = isProxy ? '9router-proxy' : `${authProviderName}:default`;
220
- const authKeyValue = isProxy
221
- ? proxyKey
222
- : (apiKey || `<your_${(provider.envKey || 'API_KEY').toLowerCase()}>`);
223
- const json = {
224
- version: 1,
225
- profiles: {
226
- [authProfileId]: {
227
- provider: authProviderName,
228
- type: 'api_key',
229
- key: authKeyValue,
230
- },
231
- },
232
- order: { [authProviderName]: [authProfileId] },
233
- };
234
-
235
- if (!isProxy && providerKey !== 'openai' && provider.baseURL) {
236
- json.profiles[authProfileId].url = provider.baseURL;
237
- }
238
- return json;
239
- }
240
-
241
- function buildAuthProfilesString(options = {}) {
242
- return JSON.stringify(buildAuthProfilesJson(options), null, 2);
243
- }
244
-
245
- function get9RouterBaseUrl(deployMode = 'native') {
246
- return deployMode === 'docker' ? `${NINE_ROUTER_DOCKER_API_BASE_URL}/v1` : `${NINE_ROUTER_API_BASE_URL}/v1`;
247
- }
248
-
249
- function build9RouterProviderConfig(baseUrl = `${NINE_ROUTER_API_BASE_URL}/v1`) {
250
- return {
251
- baseUrl,
252
- apiKey: NINE_ROUTER_PROXY_API_KEY,
253
- api: 'openai-completions',
254
- models: [
255
- {
256
- id: 'smart-route',
257
- name: 'Smart Proxy (Auto Route)',
258
- contextWindow: 200000,
259
- maxTokens: 8192,
260
- },
261
- ...SUPPORTED_CODEX_MODELS.map((id) => ({
262
- id,
263
- name: `Codex ${id.slice(3).replace(/-/g, ' ').replace(/\b\w/g, (char) => char.toUpperCase())}`,
264
- contextWindow: 200000,
265
- maxTokens: 8192,
266
- })),
267
- ],
268
- };
269
- }
270
-
271
- function buildGatewayConfig(port = 18791, deployMode = 'native', allowedOrigins = [], osChoice = '') {
272
- const normalizedPort = Number(port) || 18791;
273
- const cfg = {
274
- port: normalizedPort,
275
- mode: 'local',
276
- controlUi: { allowedOrigins },
277
- auth: { mode: 'token', token: crypto.randomUUID().replace(/-/g, '') },
278
- };
279
- if (deployMode === 'docker' || osChoice === 'vps') {
280
- cfg.bind = 'custom';
281
- cfg.customBindHost = '0.0.0.0';
282
- } else {
283
- cfg.bind = 'loopback';
284
- }
285
- return cfg;
286
- }
287
-
288
- root.__openclawCommon = {
289
- OPENCLAW_NPM_SPEC,
290
- OPENCLAW_RUNTIME_PACKAGES,
291
- NINE_ROUTER_NPM_SPEC,
292
- NINE_ROUTER_PORT,
293
- NINE_ROUTER_PROXY_API_KEY,
294
- NINE_ROUTER_API_BASE_URL,
295
- NINE_ROUTER_DOCKER_API_BASE_URL,
296
- SUPPORTED_CODEX_MODELS,
297
- SMART_ROUTE_PROVIDER_MODELS,
298
- SMART_ROUTE_PROVIDER_ORDER,
299
- TELEGRAM_RELAY_PLUGIN_SPEC,
300
- TELEGRAM_RELAY_PLUGIN_ID,
301
- TELEGRAM_SETUP_GUIDE_FILENAME,
302
- buildRelayPluginInstallCommand,
303
- buildRelayPluginInstallCommandWin,
304
- buildTelegramPostInstallChecklist,
305
- buildAuthProfilesJson,
306
- buildAuthProfilesString,
307
- get9RouterBaseUrl,
308
- build9RouterProviderConfig,
309
- buildGatewayConfig,
310
- };
311
-
312
- })(typeof globalThis !== 'undefined' ? globalThis : {});
313
- if (typeof exports !== 'undefined' && typeof globalThis !== 'undefined' && globalThis.__openclawCommon) {
314
- Object.assign(exports, globalThis.__openclawCommon);
315
- }
1
+ // @ts-nocheck
2
+ (function (root) {
3
+ const OPENCLAW_NPM_SPEC = 'openclaw@latest';
4
+ const OPENCLAW_RUNTIME_PACKAGES = 'grammy @grammyjs/runner @grammyjs/transformer-throttler @buape/carbon @larksuiteoapi/node-sdk @slack/web-api';
5
+ const NINE_ROUTER_NPM_SPEC = '9router@latest';
6
+ const NINE_ROUTER_PORT = 20128;
7
+ const NINE_ROUTER_PROXY_API_KEY = 'sk-no-key';
8
+ const NINE_ROUTER_API_BASE_URL = `http://localhost:${NINE_ROUTER_PORT}`;
9
+ const NINE_ROUTER_DOCKER_API_BASE_URL = `http://9router:${NINE_ROUTER_PORT}`;
10
+ const SUPPORTED_CODEX_MODELS = ['cx/gpt-5.4', 'cx/gpt-5.3-codex', 'cx/gpt-5.2', 'cx/gpt-5.4-mini'];
11
+ const SMART_ROUTE_PROVIDER_MODELS = {
12
+ codex: SUPPORTED_CODEX_MODELS,
13
+ 'claude-code': ['cc/claude-opus-4-7', 'cc/claude-opus-4-6', 'cc/claude-sonnet-4-6', 'cc/claude-opus-4-5-20251101', 'cc/claude-sonnet-4-5-20250929', 'cc/claude-haiku-4-5-20251001'],
14
+ github: ['gh/gpt-5.4', 'gh/gpt-5.3-codex', 'gh/gpt-5.2-codex', 'gh/gpt-5.2', 'gh/gpt-5.1-codex-max', 'gh/gpt-5.1-codex', 'gh/gpt-5.1-codex-mini', 'gh/gpt-5.1', 'gh/gpt-5-codex', 'gh/gpt-5', 'gh/gpt-4.1', 'gh/gpt-4o', 'gh/claude-opus-4.6', 'gh/claude-sonnet-4.6', 'gh/claude-sonnet-4.5', 'gh/claude-opus-4.5', 'gh/claude-haiku-4.5', 'gh/gemini-3-pro-preview', 'gh/gemini-3-flash-preview', 'gh/gemini-2.5-pro', 'gh/grok-code-fast-1'],
15
+ cursor: ['cu/default', 'cu/claude-4.6-opus-max', 'cu/claude-4.6-sonnet-medium-thinking', 'cu/claude-4.5-opus-high-thinking', 'cu/claude-4.5-opus-high', 'cu/claude-4.5-sonnet-thinking', 'cu/claude-4.5-sonnet', 'cu/claude-4.5-haiku', 'cu/claude-4.5-opus', 'cu/gpt-5.3-codex', 'cu/gpt-5.2-codex', 'cu/gpt-5.2', 'cu/kimi-k2.5', 'cu/gemini-3-flash-preview'],
16
+ kilo: ['kc/anthropic/claude-sonnet-4-20250514', 'kc/anthropic/claude-opus-4-20250514', 'kc/google/gemini-2.5-pro', 'kc/google/gemini-2.5-flash', 'kc/openai/gpt-4.1', 'kc/openai/o3', 'kc/deepseek/deepseek-chat', 'kc/deepseek/deepseek-reasoner'],
17
+ cline: ['cl/anthropic/claude-opus-4.7', 'cl/anthropic/claude-sonnet-4.6', 'cl/anthropic/claude-opus-4.6', 'cl/openai/gpt-5.4', 'cl/openai/gpt-5.3-codex', 'cl/google/gemini-3.1-pro-preview', 'cl/google/gemini-3.1-flash-lite-preview', 'cl/kwaipilot/kat-coder-pro'],
18
+ 'gemini-cli': ['gc/gemini-3-flash-preview', 'gc/gemini-3-pro-preview'],
19
+ kiro: ['kr/claude-sonnet-4.5', 'kr/claude-haiku-4.5', 'kr/deepseek-3.2', 'kr/deepseek-3.1', 'kr/qwen3-coder-next', 'kr/glm-5', 'kr/MiniMax-M2.5'],
20
+ 'kimi-coding': ['kmc/kimi-k2.5', 'kmc/kimi-k2.5-thinking', 'kmc/kimi-latest'],
21
+ openai: ['openai/gpt-5.4', 'openai/gpt-5.4-mini', 'openai/gpt-5.2', 'openai/gpt-5.1', 'openai/gpt-5', 'openai/gpt-4o', 'openai/gpt-4.1', 'openai/o3', 'openai/o4-mini'],
22
+ anthropic: ['anthropic/claude-sonnet-4-20250514', 'anthropic/claude-opus-4-20250514', 'anthropic/claude-3-5-sonnet-20241022'],
23
+ gemini: ['gemini/gemini-3.1-pro-preview', 'gemini/gemini-3-flash-preview', 'gemini/gemini-2.5-pro', 'gemini/gemini-2.5-flash', 'gemini/gemini-2.5-flash-lite'],
24
+ deepseek: ['deepseek/deepseek-chat', 'deepseek/deepseek-reasoner'],
25
+ xai: ['xai/grok-4', 'xai/grok-4-fast-reasoning', 'xai/grok-code-fast-1', 'xai/grok-3'],
26
+ mistral: ['mistral/mistral-large-latest', 'mistral/codestral-latest', 'mistral/mistral-medium-latest'],
27
+ iflow: ['if/qwen3-coder-plus', 'if/qwen3-max', 'if/qwen3-vl-plus', 'if/qwen3-max-preview', 'if/qwen3-235b', 'if/qwen3-32b', 'if/kimi-k2', 'if/deepseek-v3.2', 'if/deepseek-v3.1', 'if/deepseek-v3', 'if/deepseek-r1', 'if/glm-4.7', 'if/iflow-rome-30ba3b'],
28
+ qwen: ['qw/qwen3-coder-plus', 'qw/qwen3-coder-flash', 'qw/vision-model', 'qw/coder-model'],
29
+ alicode: ['alicode/qwen3.5-plus', 'alicode/kimi-k2.5', 'alicode/glm-5', 'alicode/qwen3-coder-next', 'alicode/qwen3-coder-plus', 'alicode/glm-4.7'],
30
+ groq: ['groq/llama-3.3-70b-versatile', 'groq/openai/gpt-oss-120b', 'groq/qwen/qwen3-32b'],
31
+ cerebras: ['cerebras/gpt-oss-120b', 'cerebras/zai-glm-4.7', 'cerebras/qwen-3-32b'],
32
+ glm: ['glm/glm-5.1', 'glm/glm-5', 'glm/glm-4.7'],
33
+ 'glm-cn': ['glm-cn/glm-5.1', 'glm-cn/glm-5', 'glm-cn/glm-4.7', 'glm-cn/glm-4.6'],
34
+ minimax: ['minimax/MiniMax-M2.7', 'minimax/MiniMax-M2.5', 'minimax/MiniMax-M2.1'],
35
+ kimi: ['kimi/kimi-k2.5', 'kimi/kimi-k2.5-thinking', 'kimi/kimi-latest'],
36
+ ollama: ['ollama/qwen3.5', 'ollama/kimi-k2.5', 'ollama/glm-5', 'ollama/minimax-m2.5', 'ollama/glm-4.7-flash', 'ollama/gpt-oss:120b'],
37
+ };
38
+ const SMART_ROUTE_PROVIDER_ORDER = ['openai', 'anthropic', 'claude-code', 'codex', 'cursor', 'github', 'cline', 'kimi', 'minimax', 'deepseek', 'glm', 'alicode', 'xai', 'mistral', 'kilo', 'kiro', 'iflow', 'qwen', 'gemini-cli', 'gemini', 'ollama'];
39
+ const TELEGRAM_RELAY_PLUGIN_SPEC = 'openclaw-telegram-multibot-relay';
40
+ const TELEGRAM_RELAY_PLUGIN_ID = 'telegram-multibot-relay';
41
+ const TELEGRAM_SETUP_GUIDE_FILENAME = 'TELEGRAM-GROUP-SETUP.md';
42
+
43
+ function buildRelayPluginInstallCommand(prefix = 'openclaw') {
44
+ return `if [ ! -d "$OPENCLAW_STATE_DIR/extensions/${TELEGRAM_RELAY_PLUGIN_ID}" ]; then ${prefix} plugins install ${TELEGRAM_RELAY_PLUGIN_SPEC} 2>/dev/null || true; fi`;
45
+ }
46
+
47
+ function buildRelayPluginInstallCommandWin(prefix = 'openclaw') {
48
+ return `if not exist ".openclaw\\extensions\\${TELEGRAM_RELAY_PLUGIN_ID}\\" ${prefix} plugins install ${TELEGRAM_RELAY_PLUGIN_SPEC} || exit /b 0`;
49
+ }
50
+
51
+ function buildTelegramPostInstallChecklist(options = {}) {
52
+ const {
53
+ isVi = true,
54
+ bots = [],
55
+ groupId = '',
56
+ relayPluginSpec = TELEGRAM_RELAY_PLUGIN_SPEC,
57
+ includeTokenPreview = false,
58
+ } = options;
59
+ const botList = bots.map((bot, idx) => {
60
+ const name = bot?.name || `Bot ${idx + 1}`;
61
+ if (includeTokenPreview) {
62
+ return `- **${name}** — token: ${String(bot?.token || '').slice(0, 10)}...`;
63
+ }
64
+ return `- **${name}**`;
65
+ }).join('\n');
66
+
67
+ if (isVi) {
68
+ return `# Telegram Group Setup Guide
69
+
70
+ Bot da duoc cai dat. Thuc hien cac buoc sau de hoat dong trong group.
71
+
72
+ ## Group ID
73
+ - ${groupId ? `Group ID: ${groupId}` : 'Chua nhap Group ID - bot se hoat dong o moi group.'}
74
+
75
+ ## Danh sach bot
76
+ ${botList}
77
+
78
+ ---
79
+
80
+ ## Buoc 1 -- Tat Privacy Mode tren BotFather (bat buoc, lam truoc)
81
+
82
+ Mac dinh bot chi doc tin nhan bat dau bang /. Phai tat Privacy Mode thi bot moi doc duoc tat ca tin nhan trong group.
83
+
84
+ Lam lan luot cho TUNG BOT:
85
+ 1. Mo Telegram, tim @BotFather
86
+ 2. Gui: /mybots
87
+ 3. Chon bot can sua
88
+ 4. Chon: Bot Settings
89
+ 5. Chon: Group Privacy
90
+ 6. Chon: Turn off
91
+ 7. BotFather se bao: "Privacy mode is disabled for ..."
92
+
93
+ !!! QUAN TRONG: Phai lam buoc nay TRUOC khi add bot vao group. Neu bot da o trong group roi thi phai Remove bot ra, sau do Add lai.
94
+
95
+ ## Buoc 2 -- Add bot vao group
96
+
97
+ Sau khi tat Privacy Mode cho ALL bot:
98
+ 1. Mo group Telegram cua ban
99
+ 2. Vao Settings -> Members -> Add Members
100
+ 3. Tim ten tung bot theo username (VD: @TenCuaBot) va add vao
101
+ 4. Sau khi add, vao Settings -> Administrators
102
+ 5. Promote tung bot len Admin (can quyen phan hoi, co the de mac dinh)
103
+
104
+ Lay username that cua bot: vao @BotFather -> /mybots -> chon bot -> username la chu sau @.
105
+
106
+ ## Buoc 3 -- Lay Group ID (neu chua co)
107
+
108
+ 1. Them @userinfobot vao group nhu admin
109
+ 2. Go /start hoac forward bat ky tin nhan trong group cho @userinfobot
110
+ 3. Bot tra ve Chat ID bat dau bang -100...
111
+ 4. Dat gia tri do vao TELEGRAM_GROUP_ID trong file .env
112
+
113
+ ## Buoc 4 -- Cai plugin (neu chua cai duoc tu dong)
114
+
115
+ Neu trong qua trinh setup bao loi cai plugin, sau khi bot dang chay hay chay:
116
+
117
+ openclaw plugins install ${relayPluginSpec}
118
+
119
+ ## Buoc 5 -- Test
120
+
121
+ 1. Gui tin nhan trong group, mention bot: @TenCuaBot xin chao
122
+ 2. Bot se phan hoi
123
+ 3. Neu khong phan hoi: kiem tra lai Buoc 1 (Privacy Mode) va Buoc 2 (add lai sau khi tat privacy)
124
+
125
+ ---
126
+ *Generated by OpenClaw Setup*
127
+ `;
128
+ }
129
+
130
+ return `# Telegram Group Setup Guide
131
+
132
+ Bots are installed. Complete the steps below to activate them in a group.
133
+
134
+ ## Group ID
135
+ - ${groupId ? `Group ID: ${groupId}` : 'No Group ID - bots will respond in any group.'}
136
+
137
+ ## Bot list
138
+ ${botList}
139
+
140
+ ---
141
+
142
+ ## Step 1 -- Disable Privacy Mode on BotFather (required, do this first)
143
+
144
+ By default bots only read messages starting with /. You must disable Privacy Mode so bots can read all group messages.
145
+
146
+ Do this for EACH BOT:
147
+ 1. Open Telegram, find @BotFather
148
+ 2. Send: /mybots
149
+ 3. Select the bot
150
+ 4. Choose: Bot Settings
151
+ 5. Choose: Group Privacy
152
+ 6. Choose: Turn off
153
+ 7. BotFather confirms: "Privacy mode is disabled for ..."
154
+
155
+ !!! IMPORTANT: Do this BEFORE adding the bot to the group. If the bot is already in the group, remove it first then re-add it.
156
+
157
+ ## Step 2 -- Add bots to the group
158
+
159
+ After disabling Privacy Mode for ALL bots:
160
+ 1. Open your Telegram group
161
+ 2. Go to Settings -> Members -> Add Members
162
+ 3. Search each bot by username (e.g. @YourBotUsername) and add it
163
+ 4. Go to Settings -> Administrators
164
+ 5. Promote each bot to Admin
165
+
166
+ To get each bot's real username: open @BotFather -> /mybots -> select bot -> username after @.
167
+
168
+ ## Step 3 -- Get Group ID (if not already set)
169
+
170
+ 1. Add @userinfobot to the group as admin
171
+ 2. Send /start or forward any group message to @userinfobot
172
+ 3. It returns a Chat ID starting with -100...
173
+ 4. Set that value as TELEGRAM_GROUP_ID in your .env file
174
+
175
+ ## Step 4 -- Install plugin (if auto-install failed)
176
+
177
+ If setup reported a plugin install error, run this after the bot is running:
178
+
179
+ openclaw plugins install ${relayPluginSpec}
180
+
181
+ ## Step 5 -- Test
182
+
183
+ 1. Send a message in the group mentioning the bot: @YourBotUsername hello
184
+ 2. The bot should respond
185
+ 3. No response? Re-check Step 1 (Privacy Mode) and Step 2 (re-add bot after disabling privacy)
186
+
187
+ ---
188
+ *Generated by OpenClaw Setup*
189
+ `;
190
+ }
191
+
192
+ function buildAuthProfilesJson(options = {}) {
193
+ const {
194
+ providerKey = '',
195
+ provider = {},
196
+ apiKey = '',
197
+ isProxy = false,
198
+ isLocal = false,
199
+ localUrl = 'http://ollama:11434',
200
+ proxyKey = 'sk-no-key',
201
+ } = options;
202
+
203
+ if (isLocal) {
204
+ return {
205
+ version: 1,
206
+ profiles: {
207
+ 'ollama:default': {
208
+ provider: 'ollama',
209
+ type: 'api_key',
210
+ key: 'ollama-local',
211
+ url: localUrl,
212
+ },
213
+ },
214
+ order: { ollama: ['ollama:default'] },
215
+ };
216
+ }
217
+
218
+ const authProviderName = isProxy ? '9router' : providerKey;
219
+ const authProfileId = isProxy ? '9router-proxy' : `${authProviderName}:default`;
220
+ const authKeyValue = isProxy
221
+ ? proxyKey
222
+ : (apiKey || `<your_${(provider.envKey || 'API_KEY').toLowerCase()}>`);
223
+ const json = {
224
+ version: 1,
225
+ profiles: {
226
+ [authProfileId]: {
227
+ provider: authProviderName,
228
+ type: 'api_key',
229
+ key: authKeyValue,
230
+ },
231
+ },
232
+ order: { [authProviderName]: [authProfileId] },
233
+ };
234
+
235
+ if (!isProxy && providerKey !== 'openai' && provider.baseURL) {
236
+ json.profiles[authProfileId].url = provider.baseURL;
237
+ }
238
+ return json;
239
+ }
240
+
241
+ function buildAuthProfilesString(options = {}) {
242
+ return JSON.stringify(buildAuthProfilesJson(options), null, 2);
243
+ }
244
+
245
+ function get9RouterBaseUrl(deployMode = 'native', routerPort) {
246
+ const port = routerPort || NINE_ROUTER_PORT;
247
+ return deployMode === 'docker' ? `http://9router:${port}/v1` : `http://localhost:${port}/v1`;
248
+ }
249
+
250
+ function build9RouterProviderConfig(baseUrl = `${NINE_ROUTER_API_BASE_URL}/v1`) {
251
+ return {
252
+ baseUrl,
253
+ apiKey: NINE_ROUTER_PROXY_API_KEY,
254
+ api: 'openai-completions',
255
+ request: {
256
+ allowPrivateNetwork: true,
257
+ },
258
+ models: [
259
+ {
260
+ id: 'smart-route',
261
+ name: 'Smart Proxy (Auto Route)',
262
+ contextWindow: 200000,
263
+ maxTokens: 8192,
264
+ },
265
+ ],
266
+ };
267
+ }
268
+
269
+ function buildGatewayConfig(port = 18789, deployMode = 'native', allowedOrigins = [], osChoice = '') {
270
+ const normalizedPort = Number(port) || 18789;
271
+ const cfg = {
272
+ port: normalizedPort,
273
+ mode: 'local',
274
+ controlUi: { allowedOrigins },
275
+ auth: { mode: 'token', token: crypto.randomUUID().replace(/-/g, '') },
276
+ };
277
+ if (deployMode === 'docker' || osChoice === 'vps') {
278
+ cfg.bind = 'custom';
279
+ cfg.customBindHost = '0.0.0.0';
280
+ } else {
281
+ cfg.bind = 'loopback';
282
+ }
283
+ return cfg;
284
+ }
285
+
286
+ root.__openclawCommon = {
287
+ OPENCLAW_NPM_SPEC,
288
+ OPENCLAW_RUNTIME_PACKAGES,
289
+ NINE_ROUTER_NPM_SPEC,
290
+ NINE_ROUTER_PORT,
291
+ NINE_ROUTER_PROXY_API_KEY,
292
+ NINE_ROUTER_API_BASE_URL,
293
+ NINE_ROUTER_DOCKER_API_BASE_URL,
294
+ SUPPORTED_CODEX_MODELS,
295
+ SMART_ROUTE_PROVIDER_MODELS,
296
+ SMART_ROUTE_PROVIDER_ORDER,
297
+ TELEGRAM_RELAY_PLUGIN_SPEC,
298
+ TELEGRAM_RELAY_PLUGIN_ID,
299
+ TELEGRAM_SETUP_GUIDE_FILENAME,
300
+ buildRelayPluginInstallCommand,
301
+ buildRelayPluginInstallCommandWin,
302
+ buildTelegramPostInstallChecklist,
303
+ buildAuthProfilesJson,
304
+ buildAuthProfilesString,
305
+ get9RouterBaseUrl,
306
+ build9RouterProviderConfig,
307
+ buildGatewayConfig,
308
+ };
309
+
310
+ })(typeof globalThis !== 'undefined' ? globalThis : {});
311
+ if (typeof exports !== 'undefined' && typeof globalThis !== 'undefined' && globalThis.__openclawCommon) {
312
+ Object.assign(exports, globalThis.__openclawCommon);
313
+ }