create-openclaw-bot 5.7.10 → 5.8.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/README.md +61 -219
- package/README.vi.md +63 -216
- package/dist/cli.js +92 -2777
- package/dist/legacy-cli.js +2812 -0
- package/dist/server/local-server.js +2568 -0
- package/dist/setup/data/header.js +80 -80
- package/dist/setup/data/index.js +0 -1
- package/dist/setup/data/plugins.js +8 -1
- package/dist/setup/data/skills.js +2 -10
- package/dist/setup/shared/bot-config-gen.js +469 -462
- package/dist/setup/shared/common-gen.js +313 -315
- package/dist/setup/shared/docker-gen.js +193 -124
- package/dist/setup/shared/install-gen.js +566 -566
- package/dist/setup/shared/workspace-gen.js +813 -525
- package/dist/setup.js +729 -499
- package/dist/web/app.js +1247 -0
- package/dist/web/bvvbank.jpg +0 -0
- package/dist/web/index.html +14 -0
- package/dist/web/momo.jpg +0 -0
- package/dist/web/openclaw-logo.png +0 -0
- package/dist/web/openclaw-logo.svg +1 -0
- package/dist/web/styles.css +1375 -0
- package/package.json +40 -39
|
@@ -1,315 +1,313 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
(function (root) {
|
|
3
|
-
const OPENCLAW_NPM_SPEC = 'openclaw@
|
|
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
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
mode: '
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
cfg.
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
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
|
+
}
|