create-openclaw-bot 5.4.1 → 5.5.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.
package/old_v510.js ADDED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-openclaw-bot",
3
- "version": "5.4.1",
3
+ "version": "5.5.0",
4
4
  "description": "Interactive CLI installer for OpenClaw Bot",
5
5
  "main": "cli.js",
6
6
  "bin": {
@@ -0,0 +1,164 @@
1
+ // @ts-nocheck
2
+ /* eslint-disable no-undef, no-unused-vars */
3
+ /**
4
+ * @fileoverview Part of the OpenClaw Setup Wizard IIFE bundle.
5
+ * This file is concatenated (not imported) — globals are shared via setup.js IIFE scope.
6
+ * Do NOT add import/export statements. Edit, then run: node build.mjs
7
+ *
8
+ * @global {object} state - Wizard UI state
9
+ * @global {object} PROVIDERS - AI provider registry
10
+ * @global {Array} SKILLS - Available skills
11
+ * @global {Array} PLUGINS - Available plugins
12
+ * @global {object} CHANNELS - Channel definitions
13
+ * @global {boolean} isVi - Vietnamese language mode
14
+ * @global {object} provider - Current primary provider config
15
+ * @global {boolean} isMultiBot - Multi-bot mode flag
16
+ * @global {boolean} hasBrowser - Browser plugin selected
17
+ * @global {boolean} is9Router - 9Router proxy mode
18
+ * @global {string} projectDir - Output project directory path
19
+ * @global {Function} getGatewayAllowedOrigins
20
+ */
21
+ // ========== Channel definitions ==========
22
+ const CHANNELS = {
23
+ telegram: {
24
+ name: 'Telegram',
25
+ envKeys: [],
26
+ envExtra: 'TELEGRAM_BOT_TOKEN=<your_bot_token>',
27
+ credSteps: [
28
+ { textVi: 'Mở Telegram → tìm <a href="https://t.me/BotFather" target="_blank">@BotFather</a> → gửi <code>/newbot</code> → đặt tên bot → copy token', textEn: 'Open Telegram → find <a href="https://t.me/BotFather" target="_blank">@BotFather</a> → send <code>/newbot</code> → name bot → copy token' },
29
+ ],
30
+ channelConfig: {
31
+ telegram: {
32
+ enabled: true,
33
+ dmPolicy: 'open',
34
+ allowFrom: ['*'],
35
+ groupPolicy: 'allowlist',
36
+ streaming: 'partial',
37
+ },
38
+ },
39
+ pluginInstall: '',
40
+ },
41
+ 'zalo-bot': {
42
+ name: 'Zalo Bot API',
43
+ envKeys: [],
44
+ envExtra: 'ZALO_BOT_TOKEN=<your_zalo_bot_token>',
45
+ credSteps: [
46
+ { textVi: '<span style="color: #fbbf24; font-weight: 500;">⚠️ LƯU Ý: Bot OA Zalo đòi hỏi bạn phải thiết lập Webhook Public (qua VPS/ngrok có HTTPS). Hãy cân nhắc dùng Zalo Personal nếu bạn chưa có Webhook.</span>', textEn: '<span style="color: #fbbf24; font-weight: 500;">⚠️ NOTE: Zalo OA Bot requires setting up a Public Webhook (using VPS/ngrok with HTTPS). Consider using Zalo Personal if you do not have a webhook.</span>' },
47
+ { textVi: 'Vào <a href="https://developers.zalo.me" target="_blank">Zalo Bot Platform</a> → Tạo bot mới → copy Bot Token', textEn: 'Go to <a href="https://developers.zalo.me" target="_blank">Zalo Bot Platform</a> → Create new bot → copy Bot Token' },
48
+ ],
49
+ channelConfig: {
50
+ zalo: {
51
+ enabled: true,
52
+ },
53
+ },
54
+ pluginInstall: '',
55
+ },
56
+ // 'telegram+zalo-personal' — Combo mode tạm ngưng, nghiên cứu thêm.
57
+ 'zalo-personal': {
58
+ name: 'Zalo Personal',
59
+ envKeys: [],
60
+ envExtra: '',
61
+ credSteps: [
62
+ { textVi: '⚠️ Zalo Personal dùng <strong>unofficial API (zca-js)</strong> — chỉ nên dùng tài khoản phụ', textEn: '⚠️ Zalo Personal uses <strong>unofficial API (zca-js)</strong> — use an alternate account' },
63
+ { textVi: 'Native setup sẽ tự chạy login và copy QR về thư mục project. Nếu cần chạy lại thủ công, dùng <code>openclaw channels login --channel zalouser --verbose</code>.', textEn: 'Native setup now auto-runs the login flow and copies the QR into the project folder. If needed, rerun it manually with <code>openclaw channels login --channel zalouser --verbose</code>.' },
64
+ ],
65
+ channelConfig: {
66
+ zalouser: {
67
+ enabled: true,
68
+ accounts: {
69
+ default: {
70
+ dmPolicy: 'open',
71
+ allowFrom: ['*'],
72
+ groupPolicy: 'allowlist',
73
+ },
74
+ },
75
+ dmPolicy: 'open',
76
+ groupPolicy: 'allowlist',
77
+ },
78
+ },
79
+ pluginInstall: '@openclaw/zalouser',
80
+ },
81
+ };
82
+
83
+ // ========== Default system prompts ==========
84
+ const DEFAULT_PROMPTS = {
85
+ vi: `Bạn là {BOT_NAME}, {BOT_DESC}.
86
+
87
+ ## Tính cách
88
+ - Thân thiện, hữu ích
89
+ - Trả lời bằng tiếng Việt
90
+ - Giọng văn tự nhiên, gần gũi
91
+
92
+ ## Quy tắc
93
+ - Trả lời ngắn gọn, súc tích
94
+ - Hỏi lại khi chưa rõ yêu cầu`,
95
+ en: `You are {BOT_NAME}, {BOT_DESC}.
96
+
97
+ ## Personality
98
+ - Friendly and helpful
99
+ - Reply in English
100
+ - Natural, conversational tone
101
+
102
+ ## Rules
103
+ - Keep answers concise
104
+ - Ask for clarification when needed`,
105
+ };
106
+
107
+ // ========== Default Security Rules ==========
108
+ const DEFAULT_SECURITY_RULES = {
109
+ vi: `## 🔐 Quy Tắc Bảo Mật — BẮT BUỘC
110
+
111
+ ### File & thư mục hệ thống
112
+ - ❌ KHÔNG đọc, sao chép, hoặc truy cập bất kỳ file nào ngoài thư mục project
113
+ - ❌ KHÔNG quét hoặc liệt kê các thư mục hệ thống: Documents, Desktop, Downloads, AppData
114
+ - ❌ KHÔNG truy cập registry, system32, hoặc Program Files
115
+ - ❌ KHÔNG cài đặt phần mềm, driver, hoặc service ngoài Docker
116
+ - ✅ CHỈ làm việc trong thư mục project
117
+
118
+ ### API key & credentials
119
+ - ❌ KHÔNG BAO GIỜ hiển thị API key, token, hoặc mật khẩu trong chat
120
+ - ❌ KHÔNG viết API key trực tiếp vào mã nguồn
121
+ - ❌ KHÔNG commit file credentials lên Git
122
+ - ✅ LUÔN lưu credentials trong file .env riêng
123
+ - ✅ LUÔN dùng biến môi trường thay vì hardcode
124
+
125
+ ### Ví crypto & tài sản số
126
+ - ❌ TUYỆT ĐỐI KHÔNG truy cập, đọc, hoặc quét các thư mục ví crypto
127
+ - ❌ KHÔNG quét clipboard (có thể chứa seed phrases)
128
+ - ❌ KHÔNG truy cập browser profile, cookie, hoặc mật khẩu đã lưu
129
+ - ❌ KHÔNG cài đặt npm package lạ (chỉ openclaw và plugin chính thức)
130
+
131
+ ### Docker
132
+ - ✅ Chỉ mount đúng thư mục cần thiết (config + workspace)
133
+ - ❌ KHÔNG mount nguyên ổ đĩa (C:/ hoặc D:/)
134
+ - ❌ KHÔNG chạy container với --privileged
135
+ - ✅ Giới hạn port expose (chỉ 38789)`,
136
+ en: `## 🔐 Security Rules — MANDATORY
137
+
138
+ ### System files & directories
139
+ - ❌ DO NOT read, copy, or access any file outside the project folder
140
+ - ❌ DO NOT scan or list system directories: Documents, Desktop, Downloads, AppData
141
+ - ❌ DO NOT access the registry, system32, or Program Files
142
+ - ❌ DO NOT install software, drivers, or services outside Docker
143
+ - ✅ ONLY work within the project folder
144
+
145
+ ### API keys & credentials
146
+ - ❌ NEVER display API keys, tokens, or passwords in chat
147
+ - ❌ DO NOT write API keys directly into source code
148
+ - ❌ DO NOT commit credential files to Git
149
+ - ✅ ALWAYS store credentials in a separate .env file
150
+ - ✅ ALWAYS use environment variables instead of hardcoding
151
+
152
+ ### Crypto wallets & digital assets
153
+ - ❌ ABSOLUTELY DO NOT access, read, or scan crypto wallet directories
154
+ - ❌ DO NOT scan the clipboard (may contain seed phrases)
155
+ - ❌ DO NOT access browser profiles, cookies, or saved passwords
156
+ - ❌ DO NOT install unknown npm packages (only openclaw and official plugins)
157
+
158
+ ### Docker
159
+ - ✅ Only mount required directories (config + workspace)
160
+ - ❌ DO NOT mount entire drives (C:/ or D:/)
161
+ - ❌ DO NOT run containers with --privileged
162
+ - ✅ Limit exposed ports (only 38789)`,
163
+ };
164
+
@@ -0,0 +1,80 @@
1
+ // @ts-nocheck
2
+ /* eslint-disable no-undef, no-unused-vars */
3
+ /**
4
+ * @fileoverview Part of the OpenClaw Setup Wizard IIFE bundle.
5
+ * This file is concatenated (not imported) — globals are shared via setup.js IIFE scope.
6
+ * Do NOT add import/export statements. Edit, then run: node build.mjs
7
+ *
8
+ * @global {object} state - Wizard UI state
9
+ * @global {object} PROVIDERS - AI provider registry
10
+ * @global {Array} SKILLS - Available skills
11
+ * @global {Array} PLUGINS - Available plugins
12
+ * @global {object} CHANNELS - Channel definitions
13
+ * @global {boolean} isVi - Vietnamese language mode
14
+ * @global {object} provider - Current primary provider config
15
+ * @global {boolean} isMultiBot - Multi-bot mode flag
16
+ * @global {boolean} hasBrowser - Browser plugin selected
17
+ * @global {boolean} is9Router - 9Router proxy mode
18
+ * @global {string} projectDir - Output project directory path
19
+ * @global {Function} getGatewayAllowedOrigins
20
+ */
21
+ // ========== CDN Logo URLs (thesvg.org) ==========
22
+ const SVG_CDN = 'https://thesvg.org/icons';
23
+ const LOGO = {
24
+ gemini: `${SVG_CDN}/google-gemini/default.svg`,
25
+ anthropic: `${SVG_CDN}/anthropic/light.svg`,
26
+ openai: `${SVG_CDN}/openai/light.svg`,
27
+ openrouter: `${SVG_CDN}/openrouter/light.svg`,
28
+ ollama: `${SVG_CDN}/ollama/light.svg`,
29
+ '9router': null, // Uses emoji icon 🔀 instead of SVG
30
+ };
31
+
32
+ // Language flag icons (inline SVG circles with flag colors)
33
+ const FLAG_ICONS = {
34
+ vi: `<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><circle cx="10" cy="10" r="10" fill="#DA251D"/><polygon points="10,4 11.5,8.5 16,8.5 12.3,11.2 13.8,15.7 10,13 6.2,15.7 7.7,11.2 4,8.5 8.5,8.5" fill="#FFFF00"/></svg>`,
35
+ en: `<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><circle cx="10" cy="10" r="10" fill="#012169"/><path d="M0 0L20 20M20 0L0 20" stroke="white" stroke-width="3"/><path d="M0 0L20 20M20 0L0 20" stroke="#C8102E" stroke-width="1.5"/><path d="M10 0V20M0 10H20" stroke="white" stroke-width="5"/><path d="M10 0V20M0 10H20" stroke="#C8102E" stroke-width="3"/></svg>`,
36
+ };
37
+
38
+ // ========== State ==========
39
+ const state = {
40
+ currentStep: 1,
41
+ totalSteps: 5,
42
+ channel: null,
43
+ deployMode: 'docker', // 'docker' | 'native'
44
+ nativeOs: 'win', // 'win' | 'linux' | 'vps' | 'linux-desktop'
45
+ config: {
46
+ botName: '',
47
+ description: '',
48
+ emoji: '🤖',
49
+ provider: 'google',
50
+ model: 'google/gemini-2.5-flash',
51
+ language: 'vi',
52
+ systemPrompt: '',
53
+ userInfo: '',
54
+ securityRules: '',
55
+ plugins: [],
56
+ skills: [],
57
+ // Persisted credential inputs (Bug 1+2 fix)
58
+ botToken: '',
59
+ apiKey: '',
60
+ projectPath: '',
61
+ },
62
+ };
63
+
64
+ // Runtime packages installed alongside openclaw in native and Docker flows.
65
+ const openClawRuntimePackages = globalThis.__openclawCommon?.OPENCLAW_RUNTIME_PACKAGES
66
+ || 'grammy @grammyjs/runner @grammyjs/transformer-throttler @buape/carbon @larksuiteoapi/node-sdk @slack/web-api';
67
+
68
+ function getGatewayAllowedOrigins(port) {
69
+ const normalizedPort = Number(port) || 18791;
70
+ const origins = new Set([
71
+ `http://localhost:${normalizedPort}`,
72
+ `http://127.0.0.1:${normalizedPort}`,
73
+ `http://0.0.0.0:${normalizedPort}`,
74
+ ]);
75
+ const currentHost = (window.location && window.location.hostname) ? window.location.hostname.trim() : '';
76
+ if (currentHost) {
77
+ origins.add(`http://${currentHost}:${normalizedPort}`);
78
+ }
79
+ return Array.from(origins);
80
+ }
@@ -0,0 +1,73 @@
1
+ // @ts-nocheck
2
+ /**
3
+ * setup/data/index.js — Shared data for CLI + Wizard
4
+ *
5
+ * Provides CLI-compatible views of PROVIDERS, SKILLS, CHANNELS, and OLLAMA_MODELS.
6
+ * The wizard uses these via IIFE concatenation (providers.js, skills.js, channels.js).
7
+ * The CLI imports this file directly via createRequire.
8
+ *
9
+ * Structure deliberately kept flat & forward-compatible:
10
+ * - PROVIDERS: { [key]: { name, icon, envKey?, isProxy?, isLocal? } }
11
+ * - SKILLS: [{ value, name, slug? }]
12
+ * - CHANNELS: { [key]: { name, type, icon } }
13
+ * - OLLAMA_MODELS: [{ id, name, reasoning, input, cost, contextWindow, maxTokens }]
14
+ */
15
+ (function (root) {
16
+ // ── CLI-facing PROVIDERS (display + config metadata) ──────────────────────────
17
+ // Keep in sync with setup/data/providers.js model IDs
18
+ const PROVIDERS = {
19
+ '9router': { name: '9Router Proxy (Khuyên dùng)', icon: '🔀', isProxy: true },
20
+ 'openai': { name: 'OpenAI (ChatGPT)', icon: '🧠', envKey: 'OPENAI_API_KEY' },
21
+ 'ollama': { name: 'Local Ollama', icon: '🏠', isLocal: true },
22
+ 'google': { name: 'Google (Gemini)', icon: '⚡', envKey: 'GEMINI_API_KEY' },
23
+ 'anthropic': { name: 'Anthropic (Claude)', icon: '🦄', envKey: 'ANTHROPIC_API_KEY' },
24
+ 'xai': { name: 'xAI (Grok)', icon: '✖️', envKey: 'XAI_API_KEY' },
25
+ 'groq': { name: 'Groq (LPU)', icon: '🏎️', envKey: 'GROQ_API_KEY' },
26
+ 'openrouter':{ name: 'OpenRouter', icon: '🌐', envKey: 'OPENROUTER_API_KEY' },
27
+ };
28
+
29
+ // ── CLI-facing SKILLS (value = selection key, slug = ClawHub package name) ────
30
+ // Keep in sync with setup/data/skills.js skill IDs
31
+ const SKILLS = [
32
+ { value: 'browser', name: '🌐 Browser Automation (Playwright) (⭐ Khuyên dùng)', slug: null },
33
+ { value: 'memory', name: '🧠 Long-term Memory (⭐ Khuyên dùng)', slug: 'memory' },
34
+ { value: 'scheduler', name: '⏰ Native Cron Scheduler (⭐ Khuyên dùng)', slug: null },
35
+ { value: 'rag', name: '📚 RAG / Knowledge Base', slug: 'rag' },
36
+ { value: 'image-gen', name: '🎨 Image Generation (DALL·E / Flux)', slug: 'image-gen' },
37
+ { value: 'code-interpreter', name: '💻 Code Interpreter (Python/JS)', slug: 'code-interpreter' },
38
+ { value: 'email', name: '📧 Email Assistant', slug: 'email-assistant' },
39
+ { value: 'tts', name: '🔊 Text-To-Speech (OpenAI/ElevenLabs)', slug: 'tts' },
40
+ { value: 'web-search', name: '🔍 Web Search', slug: 'web-search' },
41
+ ];
42
+
43
+ // ── CLI-facing CHANNELS ───────────────────────────────────────────────────────
44
+ // Keep in sync with setup/data/channels.js channel keys
45
+ const CHANNELS = {
46
+ 'telegram': { name: 'Telegram', type: 'telegram', icon: '🤖' },
47
+ 'zalo-bot': { name: 'Zalo OA (Bot Platform)', type: 'zalo-bot', icon: '🔑' },
48
+ 'zalo-personal': { name: 'Zalo Personal (Quét QR)', type: 'zalo-personal', icon: '📱' },
49
+ };
50
+
51
+ // ── Ollama model definitions (single source of truth for all config JSON writes) ──
52
+ // Used in: models.json per-agent, openclaw.json models.providers.ollama
53
+ const OLLAMA_MODELS = [
54
+ { id: 'gemma4:e2b', name: 'Gemma 4 E2B', reasoning: false, input: ['text'], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128000, maxTokens: 8192 },
55
+ { id: 'gemma4:e4b', name: 'Gemma 4 E4B', reasoning: false, input: ['text'], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128000, maxTokens: 8192 },
56
+ { id: 'gemma4:26b', name: 'Gemma 4 26B', reasoning: false, input: ['text'], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128000, maxTokens: 8192 },
57
+ { id: 'gemma4:31b', name: 'Gemma 4 31B', reasoning: false, input: ['text'], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128000, maxTokens: 8192 },
58
+ { id: 'qwen3:8b', name: 'Qwen 3 8B', reasoning: false, input: ['text'], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128000, maxTokens: 8192 },
59
+ { id: 'deepseek-r1:8b', name: 'DeepSeek R1 8B', reasoning: true, input: ['text'], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 64000, maxTokens: 8192 },
60
+ { id: 'llama3.3:8b', name: 'Llama 3.3 8B', reasoning: false, input: ['text'], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128000, maxTokens: 8192 },
61
+ { id: 'gemma3:12b', name: 'Gemma 3 12B', reasoning: false, input: ['text'], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128000, maxTokens: 8192 },
62
+ ];
63
+
64
+ // ── Node.js export (for CLI via createRequire) ────────────────────────────────
65
+ if (typeof module !== 'undefined' && module.exports) {
66
+ module.exports = { PROVIDERS, SKILLS, CHANNELS, OLLAMA_MODELS };
67
+ }
68
+
69
+ // ── Browser global (future use if wizard imports this directly) ───────────────
70
+ if (typeof root !== 'undefined') {
71
+ root.__openclawData = { PROVIDERS, SKILLS, CHANNELS, OLLAMA_MODELS };
72
+ }
73
+ })(typeof globalThis !== 'undefined' ? globalThis : (typeof window !== 'undefined' ? window : {}));
@@ -0,0 +1,60 @@
1
+ // @ts-nocheck
2
+ /* eslint-disable no-undef, no-unused-vars */
3
+ /**
4
+ * @fileoverview Part of the OpenClaw Setup Wizard IIFE bundle.
5
+ * This file is concatenated (not imported) — globals are shared via setup.js IIFE scope.
6
+ * Do NOT add import/export statements. Edit, then run: node build.mjs
7
+ *
8
+ * @global {object} state - Wizard UI state
9
+ * @global {object} PROVIDERS - AI provider registry
10
+ * @global {Array} SKILLS - Available skills
11
+ * @global {Array} PLUGINS - Available plugins
12
+ * @global {object} CHANNELS - Channel definitions
13
+ * @global {boolean} isVi - Vietnamese language mode
14
+ * @global {object} provider - Current primary provider config
15
+ * @global {boolean} isMultiBot - Multi-bot mode flag
16
+ * @global {boolean} hasBrowser - Browser plugin selected
17
+ * @global {boolean} is9Router - 9Router proxy mode
18
+ * @global {string} projectDir - Output project directory path
19
+ * @global {Function} getGatewayAllowedOrigins
20
+ */
21
+ // ========== Available Plugins (npm packages — runtime/channel extensions) ==========
22
+ const PLUGINS = [
23
+ {
24
+ id: 'telegram-multibot-relay',
25
+ name: 'Telegram Multi-Bot Relay',
26
+ icon: '🤝',
27
+ descVi: 'Điều phối nhiều bot Telegram trong cùng group — tự động khi chọn nhiều bot', descEn: 'Coordinate multiple Telegram bots in one group — auto-selected with multi-bot',
28
+ package: 'openclaw-telegram-multibot-relay',
29
+ hidden: true, // hidden in UI, auto-selected programmatically
30
+ },
31
+ {
32
+ id: 'voice-call',
33
+ name: 'Voice Call',
34
+ icon: '📞',
35
+ descVi: 'Gọi thoại AI qua điện thoại', descEn: 'AI voice calls via phone',
36
+ package: '@openclaw/voice-call',
37
+ },
38
+ {
39
+ id: 'matrix',
40
+ name: 'Matrix Chat',
41
+ icon: '💬',
42
+ descVi: 'Kết nối thêm kênh Matrix/Element', descEn: 'Connect to Matrix/Element channels',
43
+ package: '@openclaw/matrix',
44
+ },
45
+ {
46
+ id: 'msteams',
47
+ name: 'MS Teams',
48
+ icon: '🏢',
49
+ descVi: 'Kết nối Microsoft Teams', descEn: 'Connect Microsoft Teams',
50
+ package: '@openclaw/msteams',
51
+ },
52
+ {
53
+ id: 'nostr',
54
+ name: 'Nostr',
55
+ icon: '🟣',
56
+ descVi: 'Kết nối mạng xã hội Nostr', descEn: 'Connect Nostr social network',
57
+ package: '@openclaw/nostr',
58
+ },
59
+ ];
60
+
@@ -0,0 +1,121 @@
1
+ // @ts-nocheck
2
+ /* eslint-disable no-undef, no-unused-vars */
3
+ /**
4
+ * @fileoverview Part of the OpenClaw Setup Wizard IIFE bundle.
5
+ * This file is concatenated (not imported) — globals are shared via setup.js IIFE scope.
6
+ * Do NOT add import/export statements. Edit, then run: node build.mjs
7
+ *
8
+ * @global {object} state - Wizard UI state
9
+ * @global {object} PROVIDERS - AI provider registry
10
+ * @global {Array} SKILLS - Available skills
11
+ * @global {Array} PLUGINS - Available plugins
12
+ * @global {object} CHANNELS - Channel definitions
13
+ * @global {boolean} isVi - Vietnamese language mode
14
+ * @global {object} provider - Current primary provider config
15
+ * @global {boolean} isMultiBot - Multi-bot mode flag
16
+ * @global {boolean} hasBrowser - Browser plugin selected
17
+ * @global {boolean} is9Router - 9Router proxy mode
18
+ * @global {string} projectDir - Output project directory path
19
+ * @global {Function} getGatewayAllowedOrigins
20
+ */
21
+ // ========== AI Providers & Models ==========
22
+ const PROVIDERS = {
23
+ google: {
24
+ name: 'Google Gemini',
25
+ logo: LOGO.gemini,
26
+ supportsEmbeddings: true,
27
+ envKey: 'GOOGLE_API_KEY',
28
+ envLabel: 'Google AI API Key',
29
+ envLink: 'https://aistudio.google.com/apikey',
30
+ envInstructionsVi: 'Vào <a href="https://aistudio.google.com/apikey" target="_blank">aistudio.google.com/apikey</a> → Create API Key → Copy', envInstructionsEn: 'Go to <a href="https://aistudio.google.com/apikey" target="_blank">aistudio.google.com/apikey</a> → Create API Key → Copy',
31
+ free: true,
32
+ models: [
33
+ { id: 'google/gemini-2.5-flash', name: 'Gemini 2.5 Flash', descVi: 'Nhanh, miễn phí, đa năng', descEn: 'Fast, free, versatile', badge: '🆓 Free' },
34
+ { id: 'google/gemini-2.5-pro', name: 'Gemini 2.5 Pro', descVi: 'Thông minh hơn, phân tích sâu', descEn: 'Smarter, deeper analysis', badge: '🆓 Free' },
35
+ { id: 'google/gemini-3-flash', name: 'Gemini 3 Flash', descVi: 'Thế hệ mới, cực nhanh', descEn: 'Next gen, extremely fast', badge: '🆓 Free' },
36
+ ],
37
+ },
38
+ anthropic: {
39
+ name: 'Anthropic Claude',
40
+ logo: LOGO.anthropic,
41
+ supportsEmbeddings: false,
42
+ envKey: 'ANTHROPIC_API_KEY',
43
+ envLabel: 'Anthropic API Key',
44
+ envLink: 'https://console.anthropic.com/settings/keys',
45
+ envInstructionsVi: 'Vào <a href="https://console.anthropic.com/settings/keys" target="_blank">console.anthropic.com</a> → Create Key → Copy', envInstructionsEn: 'Go to <a href="https://console.anthropic.com/settings/keys" target="_blank">console.anthropic.com/settings/keys</a> → Create Key → Copy',
46
+ free: false,
47
+ models: [
48
+ { id: 'anthropic/claude-sonnet-4', name: 'Claude Sonnet 4', descVi: 'Cân bằng tốc độ & chất lượng', descEn: 'Balanced speed & quality', badge: '💰 Paid' },
49
+ { id: 'anthropic/claude-opus-4', name: 'Claude Opus 4', descVi: 'Mạnh nhất, suy luận sâu', descEn: 'Strongest, deep reasoning', badge: '💰 Paid' },
50
+ { id: 'anthropic/claude-haiku-3.5', name: 'Claude Haiku 3.5', descVi: 'Nhanh, rẻ nhất', descEn: 'Fastest, cheapest', badge: '💰 Paid' },
51
+ ],
52
+ },
53
+ openai: {
54
+ name: 'OpenAI / Codex',
55
+ logo: LOGO.openai,
56
+ supportsEmbeddings: true,
57
+ envKey: 'OPENAI_API_KEY',
58
+ envLabel: 'OpenAI API Key',
59
+ envLink: 'https://platform.openai.com/api-keys',
60
+ envInstructionsVi: 'Vào <a href="https://platform.openai.com/api-keys" target="_blank">platform.openai.com/api-keys</a> → Create new secret key → Copy. <br><strong>Lưu ý:</strong> Codex models cũng dùng chung API key này.', envInstructionsEn: 'Go to <a href="https://platform.openai.com/api-keys" target="_blank">platform.openai.com/api-keys</a> → Create new secret key → Copy. <br><strong>Note:</strong> Codex models also use this key.',
61
+ free: false,
62
+ models: [
63
+ { id: 'openai/gpt-4o', name: 'GPT-4o', descVi: 'Đa năng, nhanh', descEn: 'Versatile, rapid', badge: '💰 Paid' },
64
+ { id: 'openai/gpt-4o-mini', name: 'GPT-4o Mini', descVi: 'Rẻ, phù hợp chat', descEn: 'Cheap, good for chat', badge: '💰 Paid' },
65
+ { id: 'openai/o3', name: 'o3', descVi: 'Suy luận mạnh nhất', descEn: 'Strongest reasoning', badge: '💰 Paid' },
66
+ { id: 'openai/codex-mini', name: 'Codex Mini', descVi: 'Chuyên code, agent', descEn: 'Optimized for code/agents', badge: '💰 Paid' },
67
+ ],
68
+ },
69
+ openrouter: {
70
+ name: 'OpenRouter',
71
+ logo: LOGO.openrouter,
72
+ supportsEmbeddings: false,
73
+ envKey: 'OPENROUTER_API_KEY',
74
+ envLabel: 'OpenRouter API Key',
75
+ envLink: 'https://openrouter.ai/keys',
76
+ envInstructionsVi: 'Vào <a href="https://openrouter.ai/keys" target="_blank">openrouter.ai/keys</a> → Create Key → Copy. OpenRouter hỗ trợ nhiều model miễn phí!', envInstructionsEn: 'Go to <a href="https://openrouter.ai/keys" target="_blank">openrouter.ai/keys</a> → Create Key → Copy. OpenRouter provides many free models!',
77
+ free: true,
78
+ models: [
79
+ { id: 'openrouter/google/gemma-3-12b-it:free', name: 'Gemma 3 12B', descVi: 'Google, miễn phí', descEn: 'Google, free', badge: '🆓 Free' },
80
+ { id: 'openrouter/nvidia/nemotron-nano-9b-v2:free', name: 'Nemotron Nano 9B', descVi: 'NVIDIA, miễn phí', descEn: 'NVIDIA, free', badge: '🆓 Free' },
81
+ { id: 'openrouter/qwen/qwen3-coder:free', name: 'Qwen 3 Coder', descVi: 'Alibaba, code, miễn phí', descEn: 'Alibaba, code, free', badge: '🆓 Free' },
82
+ ],
83
+ },
84
+ ollama: {
85
+ name: 'Ollama (Local)',
86
+ logo: LOGO.ollama,
87
+ supportsEmbeddings: true,
88
+ envKey: 'OLLAMA_HOST',
89
+ envLabel: 'Ollama Host URL',
90
+ envLink: 'https://ollama.com',
91
+ envInstructionsVi: 'Cài <a href="https://ollama.com" target="_blank">Ollama</a> → chạy <code>ollama serve</code> → model chạy offline trên máy bạn.', envInstructionsEn: 'Install <a href="https://ollama.com" target="_blank">Ollama</a> → run <code>ollama serve</code> → model will run offline on your machine.',
92
+ free: true,
93
+ isLocal: true,
94
+ models: [
95
+ { id: 'ollama/gemma4:e2b', name: 'Gemma 4 E2B', descVi: '🟢 Nhẹ nhất (~4-6 GB RAM) — Edge, laptop, test nhanh', descEn: '🟢 Lightest (~4-6 GB RAM) — Edge, laptop, fastest startup', badge: '🆕 Apr 2 2026' },
96
+ { id: 'ollama/gemma4:e4b', name: 'Gemma 4 E4B', descVi: '🟡 Cân bằng (~8-10 GB RAM) — Khuyên dùng', descEn: '🟡 Balanced (~8-10 GB RAM) — Recommended', badge: '🆕 Apr 2 2026' },
97
+ { id: 'ollama/gemma4:26b', name: 'Gemma 4 26B', descVi: '🟠 Mạnh (~18-24 GB RAM/VRAM) — Máy mạnh', descEn: '🟠 Powerful (~18-24 GB RAM/VRAM) — High-end machine', badge: '🆕 Apr 2 2026' },
98
+ { id: 'ollama/gemma4:31b', name: 'Gemma 4 31B', descVi: '🔴 Mạnh nhất (~24+ GB RAM/VRAM) — Workstation/GPU', descEn: '🔴 Most powerful (~24+ GB RAM/VRAM) — Workstation/GPU', badge: '🆕 Apr 2 2026' },
99
+ { id: 'ollama/qwen3:8b', name: 'Qwen 3 8B', descVi: 'Đa ngôn ngữ, nhẹ', descEn: 'Multi-lingual, lightweight', badge: '🏠 Local' },
100
+ { id: 'ollama/deepseek-r1:8b', name: 'DeepSeek R1 8B', descVi: 'Suy luận, code', descEn: 'Reasoning, code', badge: '🏠 Local' },
101
+ { id: 'ollama/llama3.3:8b', name: 'Llama 3.3 8B', descVi: 'Meta, đa năng', descEn: 'Meta, versatile', badge: '🏠 Local' },
102
+ { id: 'ollama/gemma3:12b', name: 'Gemma 3 12B', descVi: 'Google, tiếng Việt tốt', descEn: 'Google, great logic', badge: '🏠 Local' },
103
+ ],
104
+ },
105
+ '9router': {
106
+ name: '9Router (Proxy)',
107
+ logo: null,
108
+ logoEmoji: '🔀',
109
+ supportsEmbeddings: false,
110
+ envKey: null,
111
+ envLabel: null,
112
+ envLink: 'https://github.com/decolua/9router',
113
+ envInstructionsVi: '9Router chạy cùng Docker — <strong>không cần API key</strong>. Sau khi <code>docker compose up</code>, mở <a href="http://localhost:20128/dashboard" target="_blank">localhost:20128/dashboard</a> → đăng nhập OAuth.<br>✅ <b>Mới v0.3.75:</b> Claude Code, Codex, Gemini CLI và Antigravity có thể dùng 9Router làm endpoint trực tiếp.<br><span style="color:var(--danger)">⚠️ <b>CẢNH BÁO:</b> TUYỆT ĐỐI KHÔNG chọn Provider <b>Antigravity</b> khi đăng nhập OAuth trên dashboard 9Router (nguy cơ bị ban Google Account vĩnh viễn).</span>', envInstructionsEn: '9Router runs with Docker — <strong>no API key needed</strong>. After <code>docker compose up</code>, open <a href="http://localhost:20128/dashboard" target="_blank">localhost:20128/dashboard</a> and OAuth login.<br>✅ <b>New in v0.3.75:</b> Claude Code, Codex, Gemini CLI, and Antigravity can use 9Router as their endpoint directly.<br><span style="color:var(--danger)">⚠️ <b>WARNING:</b> Do NOT select <b>Antigravity</b> as your OAuth Provider when logging into the 9Router dashboard (high risk of permanent Google Account ban).</span>',
114
+ free: true,
115
+ isProxy: true,
116
+ models: [
117
+ { id: '9router/smart-route', name: 'Smart Proxy (Auto Route)', descVi: 'Tự động luân chuyển FREE models — không tốn xu', descEn: 'Auto-routing across FREE providers — zero cost', badgeVi: '🌟 Khuyên dùng', badgeEn: '🌟 Recommended' }
118
+ ],
119
+ },
120
+ };
121
+