create-openclaw-bot 5.6.8 → 5.6.11
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 +18 -19
- package/README.vi.md +18 -19
- package/dist/cli.js +1231 -1161
- package/dist/setup/data/channels.js +11 -1
- package/dist/setup/shared/common-gen.js +86 -0
- package/dist/setup/shared/docker-gen.js +73 -30
- package/dist/setup/shared/install-gen.js +23 -3
- package/dist/setup.js +217 -121
- package/package.json +1 -1
package/dist/setup.js
CHANGED
|
@@ -280,15 +280,26 @@
|
|
|
280
280
|
channelConfig: {
|
|
281
281
|
zalouser: {
|
|
282
282
|
enabled: true,
|
|
283
|
+
defaultAccount: 'default',
|
|
283
284
|
accounts: {
|
|
284
285
|
default: {
|
|
285
286
|
dmPolicy: 'open',
|
|
286
287
|
allowFrom: ['*'],
|
|
287
288
|
groupPolicy: 'allowlist',
|
|
289
|
+
groupAllowFrom: ['*'],
|
|
288
290
|
},
|
|
289
291
|
},
|
|
290
292
|
dmPolicy: 'open',
|
|
293
|
+
allowFrom: ['*'],
|
|
291
294
|
groupPolicy: 'allowlist',
|
|
295
|
+
groupAllowFrom: ['*'],
|
|
296
|
+
historyLimit: 50,
|
|
297
|
+
groups: {
|
|
298
|
+
'*': {
|
|
299
|
+
enabled: true,
|
|
300
|
+
requireMention: false,
|
|
301
|
+
},
|
|
302
|
+
},
|
|
292
303
|
},
|
|
293
304
|
},
|
|
294
305
|
pluginInstall: '@openclaw/zalouser',
|
|
@@ -377,7 +388,6 @@
|
|
|
377
388
|
- ✅ Limit exposed ports (only 38789)`,
|
|
378
389
|
};
|
|
379
390
|
|
|
380
|
-
|
|
381
391
|
// ── PLUGINS list (setup/data/plugins.js) ───────────────────────────
|
|
382
392
|
// @ts-nocheck
|
|
383
393
|
/* eslint-disable no-undef, no-unused-vars */
|
|
@@ -617,6 +627,39 @@
|
|
|
617
627
|
const OPENCLAW_NPM_SPEC = 'openclaw@2026.4.14';
|
|
618
628
|
const OPENCLAW_RUNTIME_PACKAGES = 'grammy @grammyjs/runner @grammyjs/transformer-throttler @buape/carbon @larksuiteoapi/node-sdk @slack/web-api';
|
|
619
629
|
const NINE_ROUTER_NPM_SPEC = '9router@latest';
|
|
630
|
+
const NINE_ROUTER_PORT = 20128;
|
|
631
|
+
const NINE_ROUTER_PROXY_API_KEY = 'sk-no-key';
|
|
632
|
+
const NINE_ROUTER_API_BASE_URL = `http://localhost:${NINE_ROUTER_PORT}`;
|
|
633
|
+
const NINE_ROUTER_DOCKER_API_BASE_URL = `http://9router:${NINE_ROUTER_PORT}`;
|
|
634
|
+
const SUPPORTED_CODEX_MODELS = ['cx/gpt-5.4', 'cx/gpt-5.3-codex', 'cx/gpt-5.2', 'cx/gpt-5.4-mini'];
|
|
635
|
+
const SMART_ROUTE_PROVIDER_MODELS = {
|
|
636
|
+
codex: SUPPORTED_CODEX_MODELS,
|
|
637
|
+
'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'],
|
|
638
|
+
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'],
|
|
639
|
+
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'],
|
|
640
|
+
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'],
|
|
641
|
+
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'],
|
|
642
|
+
'gemini-cli': ['gc/gemini-3-flash-preview', 'gc/gemini-3-pro-preview'],
|
|
643
|
+
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'],
|
|
644
|
+
'kimi-coding': ['kmc/kimi-k2.5', 'kmc/kimi-k2.5-thinking', 'kmc/kimi-latest'],
|
|
645
|
+
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'],
|
|
646
|
+
anthropic: ['anthropic/claude-sonnet-4-20250514', 'anthropic/claude-opus-4-20250514', 'anthropic/claude-3-5-sonnet-20241022'],
|
|
647
|
+
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'],
|
|
648
|
+
deepseek: ['deepseek/deepseek-chat', 'deepseek/deepseek-reasoner'],
|
|
649
|
+
xai: ['xai/grok-4', 'xai/grok-4-fast-reasoning', 'xai/grok-code-fast-1', 'xai/grok-3'],
|
|
650
|
+
mistral: ['mistral/mistral-large-latest', 'mistral/codestral-latest', 'mistral/mistral-medium-latest'],
|
|
651
|
+
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'],
|
|
652
|
+
qwen: ['qw/qwen3-coder-plus', 'qw/qwen3-coder-flash', 'qw/vision-model', 'qw/coder-model'],
|
|
653
|
+
alicode: ['alicode/qwen3.5-plus', 'alicode/kimi-k2.5', 'alicode/glm-5', 'alicode/qwen3-coder-next', 'alicode/qwen3-coder-plus', 'alicode/glm-4.7'],
|
|
654
|
+
groq: ['groq/llama-3.3-70b-versatile', 'groq/openai/gpt-oss-120b', 'groq/qwen/qwen3-32b'],
|
|
655
|
+
cerebras: ['cerebras/gpt-oss-120b', 'cerebras/zai-glm-4.7', 'cerebras/qwen-3-32b'],
|
|
656
|
+
glm: ['glm/glm-5.1', 'glm/glm-5', 'glm/glm-4.7'],
|
|
657
|
+
'glm-cn': ['glm-cn/glm-5.1', 'glm-cn/glm-5', 'glm-cn/glm-4.7', 'glm-cn/glm-4.6'],
|
|
658
|
+
minimax: ['minimax/MiniMax-M2.7', 'minimax/MiniMax-M2.5', 'minimax/MiniMax-M2.1'],
|
|
659
|
+
kimi: ['kimi/kimi-k2.5', 'kimi/kimi-k2.5-thinking', 'kimi/kimi-latest'],
|
|
660
|
+
ollama: ['ollama/qwen3.5', 'ollama/kimi-k2.5', 'ollama/glm-5', 'ollama/minimax-m2.5', 'ollama/glm-4.7-flash', 'ollama/gpt-oss:120b'],
|
|
661
|
+
};
|
|
662
|
+
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'];
|
|
620
663
|
const TELEGRAM_RELAY_PLUGIN_SPEC = 'openclaw-telegram-multibot-relay';
|
|
621
664
|
const TELEGRAM_RELAY_PLUGIN_ID = 'telegram-multibot-relay';
|
|
622
665
|
const TELEGRAM_SETUP_GUIDE_FILENAME = 'TELEGRAM-GROUP-SETUP.md';
|
|
@@ -823,10 +866,60 @@
|
|
|
823
866
|
return JSON.stringify(buildAuthProfilesJson(options), null, 2);
|
|
824
867
|
}
|
|
825
868
|
|
|
869
|
+
function get9RouterBaseUrl(deployMode = 'native') {
|
|
870
|
+
return deployMode === 'docker' ? `${NINE_ROUTER_DOCKER_API_BASE_URL}/v1` : `${NINE_ROUTER_API_BASE_URL}/v1`;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
function build9RouterProviderConfig(baseUrl = `${NINE_ROUTER_API_BASE_URL}/v1`) {
|
|
874
|
+
return {
|
|
875
|
+
baseUrl,
|
|
876
|
+
apiKey: NINE_ROUTER_PROXY_API_KEY,
|
|
877
|
+
api: 'openai-completions',
|
|
878
|
+
models: [
|
|
879
|
+
{
|
|
880
|
+
id: 'smart-route',
|
|
881
|
+
name: 'Smart Proxy (Auto Route)',
|
|
882
|
+
contextWindow: 200000,
|
|
883
|
+
maxTokens: 8192,
|
|
884
|
+
},
|
|
885
|
+
...SUPPORTED_CODEX_MODELS.map((id) => ({
|
|
886
|
+
id,
|
|
887
|
+
name: `Codex ${id.slice(3).replace(/-/g, ' ').replace(/\b\w/g, (char) => char.toUpperCase())}`,
|
|
888
|
+
contextWindow: 200000,
|
|
889
|
+
maxTokens: 8192,
|
|
890
|
+
})),
|
|
891
|
+
],
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
function buildGatewayConfig(port = 18791, deployMode = 'native', allowedOrigins = []) {
|
|
896
|
+
const normalizedPort = Number(port) || 18791;
|
|
897
|
+
const cfg = {
|
|
898
|
+
port: normalizedPort,
|
|
899
|
+
mode: 'local',
|
|
900
|
+
controlUi: { allowedOrigins },
|
|
901
|
+
auth: { mode: 'token', token: crypto.randomUUID().replace(/-/g, '') },
|
|
902
|
+
};
|
|
903
|
+
if (deployMode === 'docker') {
|
|
904
|
+
cfg.bind = 'custom';
|
|
905
|
+
cfg.customBindHost = '0.0.0.0';
|
|
906
|
+
} else {
|
|
907
|
+
cfg.bind = 'loopback';
|
|
908
|
+
}
|
|
909
|
+
return cfg;
|
|
910
|
+
}
|
|
911
|
+
|
|
826
912
|
root.__openclawCommon = {
|
|
827
913
|
OPENCLAW_NPM_SPEC,
|
|
828
914
|
OPENCLAW_RUNTIME_PACKAGES,
|
|
829
915
|
NINE_ROUTER_NPM_SPEC,
|
|
916
|
+
NINE_ROUTER_PORT,
|
|
917
|
+
NINE_ROUTER_PROXY_API_KEY,
|
|
918
|
+
NINE_ROUTER_API_BASE_URL,
|
|
919
|
+
NINE_ROUTER_DOCKER_API_BASE_URL,
|
|
920
|
+
SUPPORTED_CODEX_MODELS,
|
|
921
|
+
SMART_ROUTE_PROVIDER_MODELS,
|
|
922
|
+
SMART_ROUTE_PROVIDER_ORDER,
|
|
830
923
|
TELEGRAM_RELAY_PLUGIN_SPEC,
|
|
831
924
|
TELEGRAM_RELAY_PLUGIN_ID,
|
|
832
925
|
TELEGRAM_SETUP_GUIDE_FILENAME,
|
|
@@ -835,6 +928,9 @@
|
|
|
835
928
|
buildTelegramPostInstallChecklist,
|
|
836
929
|
buildAuthProfilesJson,
|
|
837
930
|
buildAuthProfilesString,
|
|
931
|
+
get9RouterBaseUrl,
|
|
932
|
+
build9RouterProviderConfig,
|
|
933
|
+
buildGatewayConfig,
|
|
838
934
|
};
|
|
839
935
|
|
|
840
936
|
})(typeof globalThis !== 'undefined' ? globalThis : {});
|
|
@@ -1367,7 +1463,7 @@
|
|
|
1367
1463
|
L.push('set "PATH=%APPDATA%\\npm;%PATH%"');
|
|
1368
1464
|
L.push('powershell -NoProfile -Command "Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned -Force" >nul 2>&1');
|
|
1369
1465
|
L.push('echo.');
|
|
1370
|
-
L.push(isVi ? 'echo ====== OpenClaw
|
|
1466
|
+
L.push(isVi ? 'echo ====== OpenClaw - Khoi dong lai bot ======' : 'echo ====== OpenClaw - Restart Bot ======');
|
|
1371
1467
|
L.push('echo.');
|
|
1372
1468
|
L.push(isVi ? 'echo [1] Dung process openclaw cu (neu co)...' : 'echo [1] Stopping existing openclaw process (if any)...');
|
|
1373
1469
|
L.push('call openclaw gateway stop >nul 2>&1');
|
|
@@ -1381,11 +1477,20 @@
|
|
|
1381
1477
|
L.push("echo $env:DATA_DIR = '%DATA_DIR%' > \"%TEMP%\\oc-start9r.ps1\"");
|
|
1382
1478
|
L.push("echo $b = Join-Path $env:APPDATA 'npm\\9router.cmd' >> \"%TEMP%\\oc-start9r.ps1\"");
|
|
1383
1479
|
L.push("echo if ^(-not ^(Test-Path $b^)^) { $b = Join-Path $env:APPDATA 'npm\\9router' } >> \"%TEMP%\\oc-start9r.ps1\"");
|
|
1480
|
+
L.push(`echo $patch = Join-Path '${projectDir}' '.openclaw\\patch-9router.js' >> "%TEMP%\\oc-start9r.ps1"`);
|
|
1481
|
+
L.push("echo if ^(Test-Path $patch^) { ^& node $patch ^| Out-Null } >> \"%TEMP%\\oc-start9r.ps1\"");
|
|
1384
1482
|
L.push(`echo Start-Process 'cmd.exe' -WindowStyle Hidden -WorkingDirectory '${projectDir}' -ArgumentList ^('/c "' + $b + '" -n -H 0.0.0.0 -p 20128 --skip-update'^) >> "%TEMP%\\oc-start9r.ps1"`);
|
|
1385
1483
|
L.push('powershell -NoProfile -ExecutionPolicy Bypass -File "%TEMP%\\oc-start9r.ps1"');
|
|
1386
1484
|
L.push('del "%TEMP%\\oc-start9r.ps1" >nul 2>&1');
|
|
1387
1485
|
L.push('timeout /t 5 /nobreak >nul');
|
|
1388
1486
|
L.push(isVi ? 'echo [OK] 9Router da khoi dong.' : 'echo [OK] 9Router started.');
|
|
1487
|
+
L.push('');
|
|
1488
|
+
L.push(isVi ? 'echo [2b] Khoi dong sync smart-route...' : 'echo [2b] Starting smart-route sync...');
|
|
1489
|
+
L.push(`echo $env:DATA_DIR = '%DATA_DIR%' > "%TEMP%\\oc-syncsmart.ps1"`);
|
|
1490
|
+
L.push(`echo $sync = Join-Path '${projectDir}' '.openclaw\\9router-smart-route-sync.js' >> "%TEMP%\\oc-syncsmart.ps1"`);
|
|
1491
|
+
L.push(`echo if ^(Test-Path $sync^) { Start-Process 'node' -WindowStyle Hidden -ArgumentList $sync } >> "%TEMP%\\oc-syncsmart.ps1"`);
|
|
1492
|
+
L.push('powershell -NoProfile -ExecutionPolicy Bypass -File "%TEMP%\\oc-syncsmart.ps1"');
|
|
1493
|
+
L.push('del "%TEMP%\\oc-syncsmart.ps1" >nul 2>&1');
|
|
1389
1494
|
}
|
|
1390
1495
|
L.push('');
|
|
1391
1496
|
L.push(isVi ? 'echo [3] Khoi dong OpenClaw Gateway...' : 'echo [3] Starting OpenClaw Gateway...');
|
|
@@ -1452,7 +1557,7 @@
|
|
|
1452
1557
|
L.push(' exit 1');
|
|
1453
1558
|
L.push('fi');
|
|
1454
1559
|
L.push('');
|
|
1455
|
-
L.push(isVi ? 'echo "====== OpenClaw
|
|
1560
|
+
L.push(isVi ? 'echo "====== OpenClaw - Khoi dong lai bot qua PM2 ======"' : 'echo "====== OpenClaw - Restart Bot via PM2 ======"');
|
|
1456
1561
|
L.push('echo ""');
|
|
1457
1562
|
if (is9Router) {
|
|
1458
1563
|
L.push(isVi ? 'echo "[1] Khoi dong lai 9Router qua PM2..."' : 'echo "[1] Restarting 9Router via PM2..."');
|
|
@@ -1463,6 +1568,9 @@
|
|
|
1463
1568
|
L.push(' exit 1');
|
|
1464
1569
|
L.push('fi');
|
|
1465
1570
|
L.push('pm2 delete "$APP_NAME-9router" "$APP_NAME-9router-sync" >/dev/null 2>&1 || true');
|
|
1571
|
+
L.push('if [ -f "$PROJECT_DIR/.openclaw/patch-9router.js" ]; then');
|
|
1572
|
+
L.push(' "$NODE_BIN" "$PROJECT_DIR/.openclaw/patch-9router.js" >/dev/null 2>&1 || true');
|
|
1573
|
+
L.push('fi');
|
|
1466
1574
|
L.push('PORT=20128 HOSTNAME=0.0.0.0 DATA_DIR="$DATA_DIR" pm2 start "$NINE_ROUTER_BIN" --name "$APP_NAME-9router" --interpreter "$NODE_BIN" -- -n -H 0.0.0.0 -p 20128 --skip-update');
|
|
1467
1575
|
L.push('if [ -f "$PROJECT_DIR/.openclaw/9router-smart-route-sync.js" ]; then');
|
|
1468
1576
|
L.push(' pm2 start "$NODE_BIN" --name "$APP_NAME-9router-sync" -- "$PROJECT_DIR/.openclaw/9router-smart-route-sync.js"');
|
|
@@ -1498,7 +1606,7 @@
|
|
|
1498
1606
|
L.push('export DATA_DIR="$PWD/.9router"');
|
|
1499
1607
|
L.push('if [ -f ".env" ]; then set -a; . ./.env; set +a; fi');
|
|
1500
1608
|
L.push('');
|
|
1501
|
-
L.push(isVi ? 'echo "====== OpenClaw
|
|
1609
|
+
L.push(isVi ? 'echo "====== OpenClaw - Khoi dong lai bot ======"' : 'echo "====== OpenClaw - Restart Bot ======"');
|
|
1502
1610
|
L.push('');
|
|
1503
1611
|
L.push(isVi ? 'echo "[1] Dung openclaw gateway cu (neu co)..."' : 'echo "[1] Stopping existing openclaw gateway (if any)..."');
|
|
1504
1612
|
L.push('openclaw gateway stop 2>/dev/null || true');
|
|
@@ -1513,9 +1621,17 @@
|
|
|
1513
1621
|
L.push(isVi ? ' echo "ERROR: Khong tim thay 9router! Chay: npm install -g 9router"' : ' echo "ERROR: 9router not found! Run: npm install -g 9router"');
|
|
1514
1622
|
L.push(' exit 1');
|
|
1515
1623
|
L.push('fi');
|
|
1624
|
+
L.push('if [ -f "$PROJECT_DIR/.openclaw/patch-9router.js" ]; then');
|
|
1625
|
+
L.push(' node "$PROJECT_DIR/.openclaw/patch-9router.js" >/dev/null 2>&1 || true');
|
|
1626
|
+
L.push('fi');
|
|
1516
1627
|
L.push(`nohup env PORT=20128 HOSTNAME=0.0.0.0 DATA_DIR="$DATA_DIR" "$NINE_ROUTER_BIN" -n -H 0.0.0.0 -p 20128 --skip-update > "${logFile9r}" 2>&1 &`);
|
|
1517
1628
|
L.push('sleep 3');
|
|
1518
1629
|
L.push(isVi ? `echo "[OK] 9Router da khoi dong. Log: ${logFile9r}"` : `echo "[OK] 9Router started. Log: ${logFile9r}"`);
|
|
1630
|
+
L.push('');
|
|
1631
|
+
L.push(isVi ? 'echo "[2b] Khoi dong sync smart-route..."' : 'echo "[2b] Starting smart-route sync..."');
|
|
1632
|
+
L.push('if [ -f "$PROJECT_DIR/.openclaw/9router-smart-route-sync.js" ]; then');
|
|
1633
|
+
L.push(' nohup env DATA_DIR="$DATA_DIR" node "$PROJECT_DIR/.openclaw/9router-smart-route-sync.js" > /tmp/9router-sync.log 2>&1 &');
|
|
1634
|
+
L.push('fi');
|
|
1519
1635
|
}
|
|
1520
1636
|
L.push('');
|
|
1521
1637
|
L.push(isVi ? 'echo "[3] Khoi dong OpenClaw Gateway..."' : 'echo "[3] Starting OpenClaw Gateway..."');
|
|
@@ -1751,34 +1867,10 @@
|
|
|
1751
1867
|
// ── Shared Docker artifact helpers for wizard + CLI (setup/shared/docker-gen.js)
|
|
1752
1868
|
// @ts-nocheck
|
|
1753
1869
|
(function (root) {
|
|
1754
|
-
const
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
cursor: ['cu/default', 'cu/claude-4.6-opus-max', 'cu/claude-4.5-opus-high-thinking', 'cu/claude-4.5-sonnet-thinking', 'cu/claude-4.5-sonnet', 'cu/gpt-5.3-codex', 'cu/gpt-5.2-codex', 'cu/gemini-3-flash-preview'],
|
|
1759
|
-
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/deepseek/deepseek-chat'],
|
|
1760
|
-
cline: ['cl/anthropic/claude-sonnet-4.6', 'cl/anthropic/claude-opus-4.6', 'cl/openai/gpt-5.3-codex', 'cl/openai/gpt-5.4', 'cl/google/gemini-3.1-pro-preview'],
|
|
1761
|
-
'gemini-cli': ['gc/gemini-3-flash-preview', 'gc/gemini-3-pro-preview'],
|
|
1762
|
-
iflow: ['if/qwen3-coder-plus', 'if/kimi-k2', 'if/kimi-k2-thinking', 'if/glm-4.7', 'if/deepseek-r1', 'if/deepseek-v3.2', 'if/deepseek-v3', 'if/qwen3-max', 'if/qwen3-235b', 'if/iflow-rome-30ba3b'],
|
|
1763
|
-
qwen: ['qw/qwen3-coder-plus', 'qw/qwen3-coder-flash', 'qw/vision-model', 'qw/coder-model'],
|
|
1764
|
-
kiro: ['kr/claude-sonnet-4.5', 'kr/claude-haiku-4.5', 'kr/deepseek-3.2', 'kr/deepseek-3.1', 'kr/qwen3-coder-next'],
|
|
1765
|
-
ollama: ['ollama/gemma4:e2b', 'ollama/gemma4:e4b', 'ollama/gemma4:26b', 'ollama/gemma4:31b', 'ollama/qwen3.5', 'ollama/kimi-k2.5', 'ollama/glm-5', 'ollama/glm-4.7-flash', 'ollama/minimax-m2.5', 'ollama/gpt-oss:120b'],
|
|
1766
|
-
'kimi-coding': ['kmc/kimi-k2.5', 'kmc/kimi-k2.5-thinking', 'kmc/kimi-latest'],
|
|
1767
|
-
glm: ['glm/glm-5.1', 'glm/glm-5', 'glm/glm-4.7'],
|
|
1768
|
-
'glm-cn': ['glm/glm-5.1', 'glm/glm-5', 'glm/glm-4.7'],
|
|
1769
|
-
minimax: ['minimax/MiniMax-M2.7', 'minimax/MiniMax-M2.5', 'minimax/MiniMax-M2.1'],
|
|
1770
|
-
kimi: ['kimi/kimi-k2.5', 'kimi/kimi-k2.5-thinking', 'kimi/kimi-latest'],
|
|
1771
|
-
deepseek: ['deepseek/deepseek-chat', 'deepseek/deepseek-reasoner'],
|
|
1772
|
-
xai: ['xai/grok-4', 'xai/grok-4-fast-reasoning', 'xai/grok-code-fast-1'],
|
|
1773
|
-
mistral: ['mistral/mistral-large-latest', 'mistral/codestral-latest'],
|
|
1774
|
-
groq: ['groq/llama-3.3-70b-versatile', 'groq/openai/gpt-oss-120b'],
|
|
1775
|
-
cerebras: ['cerebras/gpt-oss-120b'],
|
|
1776
|
-
alicode: ['alicode/qwen3.5-plus', 'alicode/qwen3-coder-plus'],
|
|
1777
|
-
openai: ['openai/gpt-4o', 'openai/gpt-4.1'],
|
|
1778
|
-
anthropic: ['anthropic/claude-sonnet-4', 'anthropic/claude-haiku-3.5'],
|
|
1779
|
-
gemini: ['gemini/gemini-2.5-flash', 'gemini/gemini-2.5-pro'],
|
|
1780
|
-
};
|
|
1781
|
-
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', 'ollama'];
|
|
1870
|
+
const common = (typeof globalThis !== 'undefined' && globalThis.__openclawCommon) || {};
|
|
1871
|
+
const SUPPORTED_CODEX_MODELS = common.SUPPORTED_CODEX_MODELS || ['cx/gpt-5.4', 'cx/gpt-5.3-codex', 'cx/gpt-5.2', 'cx/gpt-5.4-mini'];
|
|
1872
|
+
const SMART_ROUTE_PROVIDER_MODELS = common.SMART_ROUTE_PROVIDER_MODELS || { codex: SUPPORTED_CODEX_MODELS };
|
|
1873
|
+
const SMART_ROUTE_PROVIDER_ORDER = common.SMART_ROUTE_PROVIDER_ORDER || ['codex'];
|
|
1782
1874
|
|
|
1783
1875
|
function encodeBase64Utf8(value) {
|
|
1784
1876
|
if (typeof Buffer !== 'undefined') {
|
|
@@ -1838,11 +1930,75 @@
|
|
|
1838
1930
|
setInterval(sync, INTERVAL);`;
|
|
1839
1931
|
}
|
|
1840
1932
|
|
|
1841
|
-
|
|
1933
|
+
function build9RouterPatchScript() {
|
|
1934
|
+
return `const fs=require('fs');const path=require('path');const cp=require('child_process');
|
|
1935
|
+
const MODELS=${JSON.stringify(SUPPORTED_CODEX_MODELS.map((model) => model.replace('cx/', '')))};
|
|
1936
|
+
const MODEL_NAMES={"gpt-5.4":"GPT 5.4","gpt-5.4-mini":"GPT 5.4 Mini","gpt-5.3-codex":"GPT 5.3 Codex","gpt-5.2":"GPT 5.2"};
|
|
1937
|
+
const SELF_TEST_BLOCK=[
|
|
1938
|
+
'codex: {',
|
|
1939
|
+
' url: "https://chatgpt.com/backend-api/codex/responses",',
|
|
1940
|
+
' method: "POST",',
|
|
1941
|
+
' authHeader: "Authorization",',
|
|
1942
|
+
' authPrefix: "Bearer ",',
|
|
1943
|
+
' extraHeaders: { "Content-Type": "application/json", "originator": "codex-cli", "User-Agent": "codex-cli/1.0.18 (macOS; arm64)" },',
|
|
1944
|
+
' body: JSON.stringify({',
|
|
1945
|
+
' model: "gpt-5.2",',
|
|
1946
|
+
' instructions: "You are a coding assistant.",',
|
|
1947
|
+
' input: [{ role: "user", content: [{ type: "input_text", text: "Reply with exactly: ok" }] }],',
|
|
1948
|
+
' stream: true,',
|
|
1949
|
+
' store: false,',
|
|
1950
|
+
' }),',
|
|
1951
|
+
' acceptStatuses: [200, 400],',
|
|
1952
|
+
' refreshable: true,',
|
|
1953
|
+
' },'
|
|
1954
|
+
].join('\\n');
|
|
1955
|
+
const roots=new Set();
|
|
1956
|
+
function add(p){if(p)roots.add(p);}
|
|
1957
|
+
try{const npmRoot=cp.execSync('npm root -g',{stdio:['ignore','pipe','ignore'],encoding:'utf8'}).trim();if(npmRoot)add(path.join(npmRoot,'9router'));}catch{}
|
|
1958
|
+
add(path.join(process.env.APPDATA||'','npm','node_modules','9router'));
|
|
1959
|
+
add('/usr/local/lib/node_modules/9router');
|
|
1960
|
+
add('/usr/lib/node_modules/9router');
|
|
1961
|
+
add(path.join(process.cwd(),'node_modules','9router'));
|
|
1962
|
+
function patchFile(filePath, transform){if(!fs.existsSync(filePath))return false;const before=fs.readFileSync(filePath,'utf8');const after=transform(before);if(!after||after===before)return false;fs.writeFileSync(filePath,after);return true;}
|
|
1963
|
+
function patchText(text,replacers){let next=text;for(const replacer of replacers){next=replacer(next);}return next===text?null:next;}
|
|
1964
|
+
function patchProviderModels(root){return patchFile(path.join(root,'open-sse','config','providerModels.js'),(text)=>text.replace(/cx:\\s*\\[[\\s\\S]*?\\],/,()=>{const lines=MODELS.map((id)=>' { id: "'+id+'", name: "'+(MODEL_NAMES[id]||id)+'" },');return 'cx: [ // OpenAI Codex\\n'+lines.join('\\n')+'\\n ],';}));}
|
|
1965
|
+
function patchCodexLikeFile(filePath){return patchFile(filePath,(text)=>{if(text.includes('max_output_tokens'))return text;return patchText(text,[
|
|
1966
|
+
(value)=>value.replace(/delete (\\w+)\\.max_tokens,delete \\1\\.user/g,'delete $1.max_tokens,delete $1.max_output_tokens,delete $1.user'),
|
|
1967
|
+
(value)=>value.replace(/delete (\\w+)\\.max_tokens;(\\s*)delete \\1\\.user/g,'delete $1.max_tokens;$2delete $1.max_output_tokens;$2delete $1.user'),
|
|
1968
|
+
(value)=>value.replace(' delete body.max_tokens;\\n',' delete body.max_tokens;\\n delete body.max_output_tokens;\\n')
|
|
1969
|
+
]);});}
|
|
1970
|
+
function patchCodexExecutor(root){let touched=0;touched+=patchCodexLikeFile(path.join(root,'open-sse','executors','codex.js'))?1:0;const chunksDir=path.join(root,'app','.next','server','chunks');if(fs.existsSync(chunksDir)){for(const entry of fs.readdirSync(chunksDir)){if(!entry.endsWith('.js'))continue;touched+=patchCodexLikeFile(path.join(chunksDir,entry))?1:0;}}return touched;}
|
|
1971
|
+
function patchResponsesNullGuard(root){let touched=0;const chunksDir=path.join(root,'app','.next','server','chunks');if(!fs.existsSync(chunksDir))return touched;for(const entry of fs.readdirSync(chunksDir)){if(!entry.endsWith('.js'))continue;touched+=patchFile(path.join(chunksDir,entry),(text)=>patchText(text,[
|
|
1972
|
+
(value)=>value.replace('let b=a.content.find(a=>"output_text"===a.type);','let b=a.content.find(a=>a&&"output_text"===a.type);'),
|
|
1973
|
+
(value)=>value.replace('let c=a.content.find(a=>"string"==typeof a.text);','let c=a.content.find(a=>a&&"string"==typeof a.text);'),
|
|
1974
|
+
(value)=>value.replace('let b=a.filter(a=>a?.type==="message");','let b=a.filter(a=>a&&a?.type==="message");'),
|
|
1975
|
+
(value)=>value.replace('for(let a of j){let b=a.type||(a.role?"message":null);','for(let a of j){let b=a&&(a.type||(a.role?"message":null));'),
|
|
1976
|
+
(value)=>value.replace('for(let a of b.messages||[]){if("system"===a.role){','for(let a of b.messages||[])if(a){if("system"===a.role){'),
|
|
1977
|
+
(value)=>value.replace('let b=Array.isArray(a.content)?a.content.map(a=>"input_text"===a.type||"output_text"===a.type?{type:"text",text:a.text}:"input_image"===a.type?{type:"image_url",image_url:{url:a.image_url||a.file_id||"",detail:a.detail||"auto"}}:a):a.content;','let b=Array.isArray(a.content)?a.content.map(a=>a&&("input_text"===a.type||"output_text"===a.type)?{type:"text",text:a.text}:a&&"input_image"===a.type?{type:"image_url",image_url:{url:a.image_url||a.file_id||"",detail:a.detail||"auto"}}:a).filter(Boolean):a.content;'),
|
|
1978
|
+
(value)=>value.replace('c="string"==typeof a.content?[{type:b,text:a.content}]:Array.isArray(a.content)?a.content.map(a=>{if("text"===a.type)return{type:b,text:a.text};if("image_url"===a.type)return{type:"input_image",image_url:"string"==typeof a.image_url?a.image_url:a.image_url?.url,detail:a.image_url?.detail||"auto"};if("input_image"===a.type)return a;let c=a.text||a.content||JSON.stringify(a);return{type:b,text:"string"==typeof c?c:JSON.stringify(c)}}):[];','c="string"==typeof a.content?[{type:b,text:a.content}]:Array.isArray(a.content)?a.content.map(a=>{if(!a)return null;if("text"===a.type)return{type:b,text:a.text};if("image_url"===a.type)return{type:"input_image",image_url:"string"==typeof a.image_url?a.image_url:a.image_url?.url,detail:a.image_url?.detail||"auto"};if("input_image"===a.type)return a;let c=a.text||a.content||JSON.stringify(a);return{type:b,text:"string"==typeof c?c:JSON.stringify(c)}}).filter(Boolean):[];'),
|
|
1979
|
+
(value)=>value.replace('b.tools&&Array.isArray(b.tools)&&(e.tools=b.tools.map(a=>{if(a.function)return a;let b=a.name;return b&&"string"==typeof b&&""!==b.trim()?{type:"function",function:{name:b,description:String(a.description||""),parameters:i(a.parameters),strict:a.strict}}:null}).filter(Boolean))','b.tools&&Array.isArray(b.tools)&&(e.tools=b.tools.map(a=>{if(!a)return null;if(a.function)return a;let b=a.name;return b&&"string"==typeof b&&""!==b.trim()?{type:"function",function:{name:b,description:String(a.description||""),parameters:i(a.parameters),strict:a.strict}}:null}).filter(Boolean))'),
|
|
1980
|
+
(value)=>value.replace('b.tools&&Array.isArray(b.tools)&&(e.tools=b.tools.map(a=>"function"===a.type?{type:"function",name:a.function.name,description:String(a.function.description||""),parameters:i(a.function.parameters),strict:a.function.strict}:a)),','b.tools&&Array.isArray(b.tools)&&(e.tools=b.tools.map(a=>a&&"function"===a.type?{type:"function",name:a.function.name,description:String(a.function.description||""),parameters:i(a.function.parameters),strict:a.function.strict}:a).filter(Boolean)),'),
|
|
1981
|
+
(value)=>value.replace('filter(a=>"function_call"===a.type)','filter(a=>a&&"function_call"===a.type)'),
|
|
1982
|
+
(value)=>value.replace(/filter\\(a=>"text"===a\\.type\\)/g,'filter(a=>a&&"text"===a.type)'),
|
|
1983
|
+
(value)=>value.replace(/find\\(a=>"message_stop"===a\\.type\\)/g,'find(a=>a&&"message_stop"===a.type)'),
|
|
1984
|
+
(value)=>value.replace(/find\\(a=>"content_block_delta"===a\\.type\\)/g,'find(a=>a&&"content_block_delta"===a.type)'),
|
|
1985
|
+
(value)=>value.replace(/find\\(a=>"message_delta"===a\\.type\\)/g,'find(a=>a&&"message_delta"===a.type)'),
|
|
1986
|
+
(value)=>value.replace(/find\\(a=>"message_start"===a\\.type\\)/g,'find(a=>a&&"message_start"===a.type)'),
|
|
1987
|
+
(value)=>value.replace(/for\\(let e of a\\.content\\)(?!if\\(e\\))/g,'for(let e of a.content)if(e)')
|
|
1988
|
+
] ))?1:0;}return touched;}
|
|
1989
|
+
function patchSelfTest(root){return patchFile(path.join(root,'src','app','api','providers','[id]','test','testUtils.js'),(text)=>{if(text.includes('model: "gpt-5.2"')&&text.includes('store: false')&&text.includes('acceptStatuses: [200, 400]'))return text;return text.replace(/codex:\\s*\\{[\\s\\S]*?refreshable:\\s*true,\\s*\\},/,SELF_TEST_BLOCK);});}
|
|
1990
|
+
let touched=0;
|
|
1991
|
+
for(const root of roots){if(!root||!fs.existsSync(root))continue;touched+=patchProviderModels(root)?1:0;touched+=patchCodexExecutor(root)?1:0;touched+=patchResponsesNullGuard(root)?1:0;touched+=patchSelfTest(root)?1:0;}
|
|
1992
|
+
if(touched){console.log('[patch-9router] Applied Codex compatibility patch.');}else{console.log('[patch-9router] No compatible 9router source files found to patch.');}`;
|
|
1993
|
+
}
|
|
1994
|
+
|
|
1995
|
+
function build9RouterComposeEntrypointScript(syncScriptBase64, patchScriptBase64) {
|
|
1842
1996
|
const nineRouterSpec = (typeof globalThis !== 'undefined' && globalThis.__openclawCommon && globalThis.__openclawCommon.NINE_ROUTER_NPM_SPEC) || '9router@latest';
|
|
1843
1997
|
return [
|
|
1844
1998
|
`npm install -g ${nineRouterSpec}`,
|
|
1999
|
+
`node -e "require('fs').writeFileSync('/tmp/patch-9router.js',Buffer.from('${patchScriptBase64}','base64').toString())"`,
|
|
1845
2000
|
`node -e "require('fs').writeFileSync('/tmp/sync.js',Buffer.from('${syncScriptBase64}','base64').toString())"`,
|
|
2001
|
+
'node /tmp/patch-9router.js || true',
|
|
1846
2002
|
'node /tmp/sync.js > /tmp/sync.log 2>&1 &',
|
|
1847
2003
|
'exec 9router -n -l -H 0.0.0.0 -p 20128 --skip-update'
|
|
1848
2004
|
].join('\n');
|
|
@@ -1930,7 +2086,9 @@
|
|
|
1930
2086
|
|
|
1931
2087
|
const syncScript = build9RouterSmartRouteSyncScript('/root/.9router/db.json');
|
|
1932
2088
|
const syncScriptBase64 = encodeBase64Utf8(syncScript);
|
|
1933
|
-
const
|
|
2089
|
+
const patchScript = build9RouterPatchScript();
|
|
2090
|
+
const patchScriptBase64 = encodeBase64Utf8(patchScript);
|
|
2091
|
+
const docker9RouterEntrypointScript = build9RouterComposeEntrypointScript(syncScriptBase64, patchScriptBase64);
|
|
1934
2092
|
const extraHostsBlock = ` extra_hosts:\n - "host.docker.internal:host-gateway"`;
|
|
1935
2093
|
|
|
1936
2094
|
const appEnvironmentBlock = ' environment:\n - OPENCLAW_HOME=/root/project/.openclaw\n - OPENCLAW_STATE_DIR=/root/project/.openclaw\n';
|
|
@@ -2139,6 +2297,7 @@
|
|
|
2139
2297
|
encodeBase64Utf8,
|
|
2140
2298
|
indentBlock,
|
|
2141
2299
|
build9RouterSmartRouteSyncScript,
|
|
2300
|
+
build9RouterPatchScript,
|
|
2142
2301
|
build9RouterComposeEntrypointScript,
|
|
2143
2302
|
buildGatewayPatchCmd,
|
|
2144
2303
|
buildDockerArtifacts,
|
|
@@ -2157,34 +2316,8 @@
|
|
|
2157
2316
|
* Do NOT add import/export statements. Edit, then run: node build.mjs
|
|
2158
2317
|
*/
|
|
2159
2318
|
|
|
2160
|
-
const SMART_ROUTE_PROVIDER_MODELS =
|
|
2161
|
-
|
|
2162
|
-
'claude-code': ['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'],
|
|
2163
|
-
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', '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'],
|
|
2164
|
-
cursor: ['cu/default', 'cu/claude-4.6-opus-max', 'cu/claude-4.5-opus-high-thinking', 'cu/claude-4.5-sonnet-thinking', 'cu/claude-4.5-sonnet', 'cu/gpt-5.3-codex', 'cu/gpt-5.2-codex', 'cu/gemini-3-flash-preview'],
|
|
2165
|
-
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/deepseek/deepseek-chat'],
|
|
2166
|
-
cline: ['cl/anthropic/claude-sonnet-4.6', 'cl/anthropic/claude-opus-4.6', 'cl/openai/gpt-5.3-codex', 'cl/openai/gpt-5.4', 'cl/google/gemini-3.1-pro-preview'],
|
|
2167
|
-
'gemini-cli': ['gc/gemini-3-flash-preview', 'gc/gemini-3-pro-preview'],
|
|
2168
|
-
iflow: ['if/qwen3-coder-plus', 'if/kimi-k2', 'if/kimi-k2-thinking', 'if/glm-4.7', 'if/deepseek-r1', 'if/deepseek-v3.2', 'if/deepseek-v3', 'if/qwen3-max', 'if/qwen3-235b', 'if/iflow-rome-30ba3b'],
|
|
2169
|
-
qwen: ['qw/qwen3-coder-plus', 'qw/qwen3-coder-flash', 'qw/vision-model', 'qw/coder-model'],
|
|
2170
|
-
kiro: ['kr/claude-sonnet-4.5', 'kr/claude-haiku-4.5', 'kr/deepseek-3.2', 'kr/deepseek-3.1', 'kr/qwen3-coder-next'],
|
|
2171
|
-
ollama: ['ollama/gemma4:e2b', 'ollama/gemma4:e4b', 'ollama/gemma4:26b', 'ollama/gemma4:31b', 'ollama/qwen3.5', 'ollama/kimi-k2.5', 'ollama/glm-5', 'ollama/glm-4.7-flash', 'ollama/minimax-m2.5', 'ollama/gpt-oss:120b'],
|
|
2172
|
-
'kimi-coding': ['kmc/kimi-k2.5', 'kmc/kimi-k2.5-thinking', 'kmc/kimi-latest'],
|
|
2173
|
-
glm: ['glm/glm-5.1', 'glm/glm-5', 'glm/glm-4.7'],
|
|
2174
|
-
'glm-cn': ['glm/glm-5.1', 'glm/glm-5', 'glm/glm-4.7'],
|
|
2175
|
-
minimax: ['minimax/MiniMax-M2.7', 'minimax/MiniMax-M2.5', 'minimax/MiniMax-M2.1'],
|
|
2176
|
-
kimi: ['kimi/kimi-k2.5', 'kimi/kimi-k2.5-thinking', 'kimi/kimi-latest'],
|
|
2177
|
-
deepseek: ['deepseek/deepseek-chat', 'deepseek/deepseek-reasoner'],
|
|
2178
|
-
xai: ['xai/grok-4', 'xai/grok-4-fast-reasoning', 'xai/grok-code-fast-1'],
|
|
2179
|
-
mistral: ['mistral/mistral-large-latest', 'mistral/codestral-latest'],
|
|
2180
|
-
groq: ['groq/llama-3.3-70b-versatile', 'groq/openai/gpt-oss-120b'],
|
|
2181
|
-
cerebras: ['cerebras/gpt-oss-120b'],
|
|
2182
|
-
alicode: ['alicode/qwen3.5-plus', 'alicode/qwen3-coder-plus'],
|
|
2183
|
-
openai: ['openai/gpt-4o', 'openai/gpt-4.1'],
|
|
2184
|
-
anthropic: ['anthropic/claude-sonnet-4', 'anthropic/claude-haiku-3.5'],
|
|
2185
|
-
gemini: ['gemini/gemini-2.5-flash', 'gemini/gemini-2.5-pro'],
|
|
2186
|
-
};
|
|
2187
|
-
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', 'ollama'];
|
|
2319
|
+
const SMART_ROUTE_PROVIDER_MODELS = globalThis.__openclawCommon.SMART_ROUTE_PROVIDER_MODELS;
|
|
2320
|
+
const SMART_ROUTE_PROVIDER_ORDER = globalThis.__openclawCommon.SMART_ROUTE_PROVIDER_ORDER;
|
|
2188
2321
|
|
|
2189
2322
|
function buildNativeScriptCtx(options) {
|
|
2190
2323
|
const relayPluginSpec = options?.relayPluginSpec || 'openclaw-telegram-multibot-relay';
|
|
@@ -2231,7 +2364,7 @@
|
|
|
2231
2364
|
const path=require('path');
|
|
2232
2365
|
const INTERVAL=30000;
|
|
2233
2366
|
const p=path.join(process.env.DATA_DIR||'.9router','db.json');
|
|
2234
|
-
const ROUTER='
|
|
2367
|
+
const ROUTER='${globalThis.__openclawCommon.NINE_ROUTER_API_BASE_URL}';
|
|
2235
2368
|
const PM=${JSON.stringify(SMART_ROUTE_PROVIDER_MODELS)};
|
|
2236
2369
|
const PREF=${JSON.stringify(SMART_ROUTE_PROVIDER_ORDER)};
|
|
2237
2370
|
console.log('[sync-combo] 9Router sync loop started...');
|
|
@@ -2426,19 +2559,9 @@
|
|
|
2426
2559
|
models: {
|
|
2427
2560
|
mode: 'merge',
|
|
2428
2561
|
providers: {
|
|
2429
|
-
'9router':
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
api: 'openai-completions',
|
|
2433
|
-
models: [
|
|
2434
|
-
{
|
|
2435
|
-
id: 'smart-route',
|
|
2436
|
-
name: 'Smart Proxy (Auto Route)',
|
|
2437
|
-
contextWindow: 200000,
|
|
2438
|
-
maxTokens: 8192,
|
|
2439
|
-
}
|
|
2440
|
-
]
|
|
2441
|
-
}
|
|
2562
|
+
'9router': globalThis.__openclawCommon.build9RouterProviderConfig(
|
|
2563
|
+
globalThis.__openclawCommon.get9RouterBaseUrl('native')
|
|
2564
|
+
)
|
|
2442
2565
|
}
|
|
2443
2566
|
}
|
|
2444
2567
|
} : {}),
|
|
@@ -2575,6 +2698,7 @@
|
|
|
2575
2698
|
// Force use global provider if proxy mode is chosen globally, else use bot specific provider
|
|
2576
2699
|
const botProvider = (provider && provider.isProxy) ? provider : (PROVIDERS[bot.provider] || provider);
|
|
2577
2700
|
const actualModel = botProvider.isProxy ? provider.models[0].id : (bot.model || state.config.model);
|
|
2701
|
+
const common = globalThis.__openclawCommon;
|
|
2578
2702
|
|
|
2579
2703
|
const cfg = {
|
|
2580
2704
|
meta: { lastTouchedVersion: '2026.3.24' },
|
|
@@ -2596,19 +2720,7 @@
|
|
|
2596
2720
|
models: {
|
|
2597
2721
|
mode: 'merge',
|
|
2598
2722
|
providers: {
|
|
2599
|
-
'9router':
|
|
2600
|
-
baseUrl: state.deployMode === 'docker' ? 'http://9router:20128/v1' : 'http://localhost:20128/v1',
|
|
2601
|
-
apiKey: 'sk-no-key',
|
|
2602
|
-
api: 'openai-completions',
|
|
2603
|
-
models: [
|
|
2604
|
-
{
|
|
2605
|
-
id: 'smart-route',
|
|
2606
|
-
name: 'Smart Proxy (Auto Route)',
|
|
2607
|
-
contextWindow: 200000,
|
|
2608
|
-
maxTokens: 8192,
|
|
2609
|
-
}
|
|
2610
|
-
]
|
|
2611
|
-
}
|
|
2723
|
+
'9router': common.build9RouterProviderConfig(common.get9RouterBaseUrl(state.deployMode))
|
|
2612
2724
|
}
|
|
2613
2725
|
}
|
|
2614
2726
|
} : {}),
|
|
@@ -2629,17 +2741,7 @@
|
|
|
2629
2741
|
commands: { native: 'auto', nativeSkills: 'auto', restart: true, ownerDisplay: 'raw' },
|
|
2630
2742
|
channels: {},
|
|
2631
2743
|
tools: { profile: 'full', exec: { host: 'gateway', security: 'full', ask: 'off' } },
|
|
2632
|
-
gateway:
|
|
2633
|
-
port: basePort,
|
|
2634
|
-
mode: 'local',
|
|
2635
|
-
...(state.deployMode === 'docker'
|
|
2636
|
-
? { bind: 'custom', customBindHost: '0.0.0.0' }
|
|
2637
|
-
: { bind: 'loopback' }),
|
|
2638
|
-
controlUi: {
|
|
2639
|
-
allowedOrigins: getGatewayAllowedOrigins(basePort),
|
|
2640
|
-
},
|
|
2641
|
-
auth: { mode: 'token', token: crypto.randomUUID().replace(/-/g, '') },
|
|
2642
|
-
},
|
|
2744
|
+
gateway: common.buildGatewayConfig(basePort, state.deployMode, getGatewayAllowedOrigins(basePort)),
|
|
2643
2745
|
};
|
|
2644
2746
|
|
|
2645
2747
|
if (hasBrowser) {
|
|
@@ -2705,7 +2807,18 @@
|
|
|
2705
2807
|
if (state.channel === 'zalo-personal') {
|
|
2706
2808
|
cfg.channels.zalouser = {
|
|
2707
2809
|
enabled: true,
|
|
2810
|
+
defaultAccount: 'default',
|
|
2708
2811
|
dmPolicy: 'open',
|
|
2812
|
+
allowFrom: ['*'],
|
|
2813
|
+
groupPolicy: 'allowlist',
|
|
2814
|
+
groupAllowFrom: ['*'],
|
|
2815
|
+
historyLimit: 50,
|
|
2816
|
+
groups: {
|
|
2817
|
+
'*': {
|
|
2818
|
+
enabled: true,
|
|
2819
|
+
requireMention: false,
|
|
2820
|
+
},
|
|
2821
|
+
},
|
|
2709
2822
|
autoReply: true,
|
|
2710
2823
|
};
|
|
2711
2824
|
// plugins.entries.zalouser is REQUIRED for gateway to load the Zalo channel provider
|
|
@@ -2740,7 +2853,7 @@
|
|
|
2740
2853
|
const authProviderName = botProvider.isProxy ? '9router' : (bot.provider || state.config.provider);
|
|
2741
2854
|
const authProfileId = botProvider.isProxy ? '9router-proxy' : `${authProviderName}:default`;
|
|
2742
2855
|
const authKeyValue = botProvider.isProxy
|
|
2743
|
-
?
|
|
2856
|
+
? globalThis.__openclawCommon.NINE_ROUTER_PROXY_API_KEY
|
|
2744
2857
|
: ((bot.apiKey || state.config.apiKey || '').trim() || `<your_${(botProvider.envKey || 'API_KEY').toLowerCase()}>`);
|
|
2745
2858
|
authProfilesJson = {
|
|
2746
2859
|
version: 1,
|
|
@@ -4808,6 +4921,7 @@
|
|
|
4808
4921
|
|
|
4809
4922
|
const buildRelayPluginInstallCommand = globalThis.__openclawCommon.buildRelayPluginInstallCommand;
|
|
4810
4923
|
const buildRelayPluginInstallCommandWin = globalThis.__openclawCommon.buildRelayPluginInstallCommandWin;
|
|
4924
|
+
const common = globalThis.__openclawCommon;
|
|
4811
4925
|
const lang = state.config.language || document.getElementById('cfg-language')?.value || 'vi';
|
|
4812
4926
|
|
|
4813
4927
|
function buildTelegramPostInstallChecklist() {
|
|
@@ -4955,34 +5069,16 @@
|
|
|
4955
5069
|
commands: { native: 'auto', nativeSkills: 'auto', restart: true, ownerDisplay: 'raw' },
|
|
4956
5070
|
channels: ch.channelConfig,
|
|
4957
5071
|
tools: { profile: 'full', exec: { host: 'gateway', security: 'full', ask: 'off' } },
|
|
4958
|
-
gateway:
|
|
4959
|
-
port: 18791,
|
|
4960
|
-
mode: 'local',
|
|
4961
|
-
bind: 'loopback',
|
|
4962
|
-
controlUi: {
|
|
4963
|
-
allowedOrigins: getGatewayAllowedOrigins(18791),
|
|
4964
|
-
},
|
|
4965
|
-
auth: { mode: 'token', token: crypto.randomUUID().replace(/-/g, '') },
|
|
4966
|
-
},
|
|
5072
|
+
gateway: common.buildGatewayConfig(18791, 'native', getGatewayAllowedOrigins(18791)),
|
|
4967
5073
|
};
|
|
4968
5074
|
|
|
4969
5075
|
// 9Router: add proxy endpoint config under models.providers
|
|
4970
5076
|
// Native mode: 9router runs on localhost; Docker mode: uses docker service hostname
|
|
4971
5077
|
if (is9Router) {
|
|
4972
|
-
const nineRouterBase = state.deployMode === 'native'
|
|
4973
|
-
? 'http://localhost:20128/v1'
|
|
4974
|
-
: 'http://9router:20128/v1';
|
|
4975
5078
|
clawConfig.models = {
|
|
4976
5079
|
mode: 'merge',
|
|
4977
5080
|
providers: {
|
|
4978
|
-
'9router':
|
|
4979
|
-
baseUrl: nineRouterBase,
|
|
4980
|
-
apiKey: 'sk-no-key',
|
|
4981
|
-
api: 'openai-completions',
|
|
4982
|
-
models: [
|
|
4983
|
-
{ id: 'smart-route', name: 'Smart Proxy (Auto Route)', contextWindow: 200000, maxTokens: 8192 }
|
|
4984
|
-
],
|
|
4985
|
-
},
|
|
5081
|
+
'9router': common.build9RouterProviderConfig(common.get9RouterBaseUrl(state.deployMode)),
|
|
4986
5082
|
},
|
|
4987
5083
|
};
|
|
4988
5084
|
}
|