openclaw-multi-auto 1.3.9 → 1.4.2
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/dist/build-info.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
9e8e5de87afb3f28d195c8ffe1cb139728ac16ea73ea35c53b2bf0158a4abb9b
|
|
@@ -4,7 +4,7 @@ import chalk, { Chalk } from "chalk";
|
|
|
4
4
|
import fs, { constants } from "node:fs";
|
|
5
5
|
import { Logger } from "tslog";
|
|
6
6
|
import os from "node:os";
|
|
7
|
-
import
|
|
7
|
+
import json5 from "json5";
|
|
8
8
|
import { isDeepStrictEqual, promisify } from "node:util";
|
|
9
9
|
import fs$1 from "node:fs/promises";
|
|
10
10
|
import { execFile, execFileSync, spawn } from "node:child_process";
|
|
@@ -802,7 +802,7 @@ function readLoggingConfig() {
|
|
|
802
802
|
try {
|
|
803
803
|
if (!fs.existsSync(configPath)) return;
|
|
804
804
|
const raw = fs.readFileSync(configPath, "utf-8");
|
|
805
|
-
const logging =
|
|
805
|
+
const logging = json5.parse(raw)?.logging;
|
|
806
806
|
if (!logging || typeof logging !== "object" || Array.isArray(logging)) return;
|
|
807
807
|
return logging;
|
|
808
808
|
} catch {
|
|
@@ -5861,7 +5861,7 @@ const defaultResolver = {
|
|
|
5861
5861
|
resolvedPath,
|
|
5862
5862
|
rootRealDir
|
|
5863
5863
|
}),
|
|
5864
|
-
parseJson: (raw) =>
|
|
5864
|
+
parseJson: (raw) => json5.parse(raw)
|
|
5865
5865
|
};
|
|
5866
5866
|
/**
|
|
5867
5867
|
* Resolves all $include directives in a parsed config object.
|
|
@@ -13216,7 +13216,7 @@ function resolveConfigPathForDeps(deps) {
|
|
|
13216
13216
|
function normalizeDeps(overrides = {}) {
|
|
13217
13217
|
return {
|
|
13218
13218
|
fs: overrides.fs ?? fs,
|
|
13219
|
-
json5: overrides.json5 ??
|
|
13219
|
+
json5: overrides.json5 ?? json5,
|
|
13220
13220
|
env: overrides.env ?? process.env,
|
|
13221
13221
|
homedir: overrides.homedir ?? (() => resolveRequiredHomeDir(overrides.env ?? process.env, os.homedir)),
|
|
13222
13222
|
configPath: overrides.configPath ?? "",
|
|
@@ -13227,11 +13227,11 @@ function maybeLoadDotEnvForConfig(env) {
|
|
|
13227
13227
|
if (env !== process.env) return;
|
|
13228
13228
|
loadDotEnv({ quiet: true });
|
|
13229
13229
|
}
|
|
13230
|
-
function parseConfigJson5(raw, json5 =
|
|
13230
|
+
function parseConfigJson5(raw, json5$1 = json5) {
|
|
13231
13231
|
try {
|
|
13232
13232
|
return {
|
|
13233
13233
|
ok: true,
|
|
13234
|
-
parsed: json5.parse(raw)
|
|
13234
|
+
parsed: json5$1.parse(raw)
|
|
13235
13235
|
};
|
|
13236
13236
|
} catch (err) {
|
|
13237
13237
|
return {
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# =================================================================
|
|
3
3
|
# OpenClaw 深度集成初始化工具 (create-instance.sh)
|
|
4
|
-
#
|
|
5
|
-
# 增强:支持环境变量 OPENCLAW_SOURCE_DIR
|
|
4
|
+
# 功能:创建实例目录、复制文件、安装依赖、配置模型、启动服务
|
|
5
|
+
# 增强:支持环境变量 OPENCLAW_SOURCE_DIR 定位源码,自动复制 docs 到根目录供 TUI 使用
|
|
6
6
|
# =================================================================
|
|
7
7
|
|
|
8
8
|
set -e
|
|
@@ -23,25 +23,21 @@ for cmd in node pnpm; do
|
|
|
23
23
|
done
|
|
24
24
|
|
|
25
25
|
# --- 1. 路径溯源与环境检查 ---
|
|
26
|
-
# 优先使用环境变量 OPENCLAW_SOURCE_DIR(可在调用脚本前设置)
|
|
27
26
|
if [ -n "$OPENCLAW_SOURCE_DIR" ] && [ -d "$OPENCLAW_SOURCE_DIR" ]; then
|
|
28
27
|
SOURCE_CODE="$OPENCLAW_SOURCE_DIR"
|
|
29
28
|
echo -e "${BLUE}📂 使用环境变量指定的源码路径: $SOURCE_CODE${NC}"
|
|
30
29
|
else
|
|
31
|
-
# 其次检查本地 pnpm 安装的路径(与部署脚本中的 openclaw-runtime 一致)
|
|
32
30
|
LOCAL_SOURCE="$HOME/openclaw-runtime/node_modules/openclaw-multi-auto"
|
|
33
31
|
if [ -d "$LOCAL_SOURCE" ]; then
|
|
34
32
|
SOURCE_CODE="$LOCAL_SOURCE"
|
|
35
33
|
echo -e "${BLUE}📂 使用本地 pnpm 安装的源码路径: $SOURCE_CODE${NC}"
|
|
36
34
|
else
|
|
37
|
-
# 最后回退到全局 npm 安装路径(兼容旧版)
|
|
38
35
|
GLOBAL_PREFIX=$(npm config get prefix)
|
|
39
36
|
SOURCE_CODE="${GLOBAL_PREFIX}/lib/node_modules/openclaw-multi-auto"
|
|
40
37
|
echo -e "${YELLOW}⚠️ 未找到环境变量和本地路径,尝试使用全局安装路径: $SOURCE_CODE${NC}"
|
|
41
38
|
fi
|
|
42
39
|
fi
|
|
43
40
|
|
|
44
|
-
# 检查源码目录是否存在
|
|
45
41
|
if [ ! -d "$SOURCE_CODE" ]; then
|
|
46
42
|
echo -e "${RED}❌ 错误: 未找到 OpenClaw 源码目录: $SOURCE_CODE${NC}"
|
|
47
43
|
echo -e "${YELLOW}请确认已正确安装 openclaw-multi-auto,或设置 OPENCLAW_SOURCE_DIR 环境变量指向正确路径。${NC}"
|
|
@@ -61,7 +57,6 @@ fi
|
|
|
61
57
|
if [ -n "$2" ]; then
|
|
62
58
|
PORT="$2"
|
|
63
59
|
else
|
|
64
|
-
# 更稳健的现有实例计数:使用 find 统计目录数
|
|
65
60
|
EXISTING_COUNT=$(find "$INSTANCES_BASE" -maxdepth 1 -type d -name "*" ! -name ".*" 2>/dev/null | wc -l | tr -d ' ')
|
|
66
61
|
PORT=$((18790 + EXISTING_COUNT))
|
|
67
62
|
fi
|
|
@@ -73,12 +68,10 @@ DIST_DIR="${INSTANCE_DIR}/dist"
|
|
|
73
68
|
echo -e "${BLUE}🏗️ 正在深度初始化实例: ${INSTANCE_NAME} (端口 ${PORT})${NC}"
|
|
74
69
|
echo "SOURCE_CODE = $SOURCE_CODE"
|
|
75
70
|
|
|
76
|
-
# 清理旧实例目录(如果存在)
|
|
77
71
|
if [ -d "$INSTANCE_DIR" ]; then
|
|
78
72
|
echo -e "${YELLOW}⚠️ 清理旧实例目录...${NC}"
|
|
79
73
|
rm -rf "$INSTANCE_DIR"
|
|
80
74
|
fi
|
|
81
|
-
# 删除可能存在的父目录 node_modules 和 workspace 文件(避免干扰)
|
|
82
75
|
[ -d "${INSTANCES_BASE}/node_modules" ] && rm -rf "${INSTANCES_BASE}/node_modules"
|
|
83
76
|
[ -f "${INSTANCES_BASE}/pnpm-workspace.yaml" ] && rm -f "${INSTANCES_BASE}/pnpm-workspace.yaml"
|
|
84
77
|
|
|
@@ -106,7 +99,6 @@ if [ -d "${SOURCE_CODE}/dist" ]; then
|
|
|
106
99
|
cp -r "${SOURCE_CODE}/dist/." "${DIST_DIR}/"
|
|
107
100
|
echo "cp exit code: $?"
|
|
108
101
|
|
|
109
|
-
# 检查所有被引用的 utils 文件是否存在
|
|
110
102
|
if [ -f "${DIST_DIR}/index.js" ]; then
|
|
111
103
|
for chunk in $(grep -oE "utils-[A-Za-z0-9]+\.js" "${DIST_DIR}/index.js" 2>/dev/null | sort -u); do
|
|
112
104
|
if [ ! -f "${DIST_DIR}/${chunk}" ]; then
|
|
@@ -124,22 +116,24 @@ fi
|
|
|
124
116
|
cp "${SOURCE_CODE}/package.json" "${INSTANCE_DIR}/package.json"
|
|
125
117
|
[ -f "${SOURCE_CODE}/pnpm-lock.yaml" ] && cp "${SOURCE_CODE}/pnpm-lock.yaml" "${INSTANCE_DIR}/pnpm-lock.yaml"
|
|
126
118
|
|
|
119
|
+
# 复制 control-ui(如果存在)
|
|
120
|
+
if [ -d "${SOURCE_CODE}/dist/control-ui" ]; then
|
|
121
|
+
cp -r "${SOURCE_CODE}/dist/control-ui" "${INSTANCE_DIR}/dist/"
|
|
122
|
+
fi
|
|
123
|
+
|
|
127
124
|
export SHARP_BINARY_HOST="https://npmmirror.com/mirrors/sharp"
|
|
128
125
|
export SHARP_LIBVIPS_BINARY_HOST="https://npmmirror.com/mirrors/sharp-libvips"
|
|
129
126
|
|
|
130
127
|
cd "${INSTANCE_DIR}"
|
|
131
128
|
echo -e "${YELLOW}📍 安装路径确认: $(pwd)${NC}"
|
|
132
129
|
|
|
133
|
-
# 检查并移除可能影响 workspace 的文件
|
|
134
130
|
if [ -f "${INSTANCES_BASE}/pnpm-workspace.yaml" ]; then
|
|
135
131
|
echo -e "${YELLOW}⚠️ 检测到 ${INSTANCES_BASE}/pnpm-workspace.yaml,临时重命名以避免干扰${NC}"
|
|
136
132
|
mv "${INSTANCES_BASE}/pnpm-workspace.yaml" "${INSTANCES_BASE}/pnpm-workspace.yaml.bak.$(date +%s)"
|
|
137
133
|
fi
|
|
138
134
|
|
|
139
|
-
# 强制安装依赖,添加 --ignore-workspace 避免 workspace 提升
|
|
140
135
|
pnpm install --shamefully-hoist --ignore-workspace --registry=https://registry.npmmirror.com --no-frozen-lockfile
|
|
141
136
|
|
|
142
|
-
# 验证 node_modules 是否生成
|
|
143
137
|
if [ ! -d "node_modules" ]; then
|
|
144
138
|
echo -e "${RED}❌ 严重错误: pnpm install 完成但 node_modules 目录未创建!${NC}"
|
|
145
139
|
exit 1
|
|
@@ -179,11 +173,9 @@ case "$MODEL_PROVIDER" in
|
|
|
179
173
|
qwen) PRIMARY_MODEL="qwen/qwen-plus"; QWEN_KEY="$API_KEY" ;;
|
|
180
174
|
esac
|
|
181
175
|
|
|
182
|
-
# 生成时间戳(兼容 macOS/Linux)
|
|
183
176
|
if date -u +"%Y-%m-%dT%H:%M:%S.%3NZ" 2>/dev/null; then
|
|
184
177
|
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%S.%3NZ")
|
|
185
178
|
else
|
|
186
|
-
# macOS 不支持 %3N,改用秒级精度
|
|
187
179
|
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")
|
|
188
180
|
fi
|
|
189
181
|
|
|
@@ -288,7 +280,6 @@ fi
|
|
|
288
280
|
cd - > /dev/null
|
|
289
281
|
rm -rf "$TEMP_DIR"
|
|
290
282
|
|
|
291
|
-
# --- 如果实例是 yunwei,安装角色包并初始化 workspace ---
|
|
292
283
|
# --- 如果实例是 yunwei,安装角色包并初始化 workspace ---
|
|
293
284
|
if [ "$INSTANCE_NAME" = "yunwei" ]; then
|
|
294
285
|
echo -e "${BLUE}🛠️ 检测到运维实例,正在安装角色包 role-openclaw-yunwei...${NC}"
|
|
@@ -298,12 +289,22 @@ if [ "$INSTANCE_NAME" = "yunwei" ]; then
|
|
|
298
289
|
TARBALL=$(ls *.tgz)
|
|
299
290
|
tar -xzf "$TARBALL" --strip-components=1
|
|
300
291
|
rm "$TARBALL"
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
292
|
+
|
|
293
|
+
# 1. 将 memory、skills 等目录复制到 workspace 根目录(排除 .md 文件)
|
|
294
|
+
for item in *; do
|
|
295
|
+
if [ -d "$item" ]; then
|
|
296
|
+
# 目录(如 memory、skills)复制到 workspace
|
|
297
|
+
cp -r "$item" "$INSTANCE_DIR/workspace/"
|
|
298
|
+
elif [ -f "$item" ] && [[ "$item" != *.md ]]; then
|
|
299
|
+
# 非 .md 文件(如 package.json)也复制到 workspace
|
|
300
|
+
cp "$item" "$INSTANCE_DIR/workspace/" 2>/dev/null || true
|
|
301
|
+
fi
|
|
302
|
+
done
|
|
303
|
+
|
|
304
|
+
# 2. 创建实例根目录下的 docs 目录,并将所有 .md 文件复制过去
|
|
305
|
+
mkdir -p "$INSTANCE_DIR/docs/reference/templates"
|
|
306
|
+
cp *.md "$INSTANCE_DIR/docs/reference/templates/" 2>/dev/null || true
|
|
307
|
+
|
|
307
308
|
echo -e "${GREEN}✅ 角色包安装完成,workspace 已初始化${NC}"
|
|
308
309
|
else
|
|
309
310
|
echo -e "${YELLOW}⚠️ 角色包下载失败,请检查网络或手动安装${NC}"
|
|
@@ -312,10 +313,6 @@ if [ "$INSTANCE_NAME" = "yunwei" ]; then
|
|
|
312
313
|
rm -rf "$TEMP_ROLE_DIR"
|
|
313
314
|
fi
|
|
314
315
|
|
|
315
|
-
if [ -d "${SOURCE_CODE}/dist/control-ui" ]; then
|
|
316
|
-
cp -r "${SOURCE_CODE}/dist/control-ui" "${INSTANCE_DIR}/dist/"
|
|
317
|
-
fi
|
|
318
|
-
|
|
319
316
|
# --- 11. 生成增强型启动脚本 ---
|
|
320
317
|
cat > "${INSTANCE_DIR}/start.sh" << 'EOF'
|
|
321
318
|
#!/usr/bin/env bash
|
|
@@ -335,7 +332,7 @@ INSTANCE_NAME=$(basename "$SCRIPT_DIR")
|
|
|
335
332
|
export OPENCLAW_CONFIG_PATH="$SCRIPT_DIR/config/openclaw.json"
|
|
336
333
|
export OPENCLAW_TMP_DIR="$SCRIPT_DIR/tmp"
|
|
337
334
|
|
|
338
|
-
# 从配置中提取 workspace
|
|
335
|
+
# 从配置中提取 workspace 路径并导出
|
|
339
336
|
if [ -f "$OPENCLAW_CONFIG_PATH" ]; then
|
|
340
337
|
export OPENCLAW_WORKSPACE=$(node -e "
|
|
341
338
|
const cfg = require('$OPENCLAW_CONFIG_PATH');
|
|
@@ -353,7 +350,7 @@ if [ -f "$OPENCLAW_CONFIG_PATH" ]; then
|
|
|
353
350
|
")
|
|
354
351
|
fi
|
|
355
352
|
|
|
356
|
-
# macOS launchd
|
|
353
|
+
# macOS launchd 守护配置(可选)
|
|
357
354
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
358
355
|
PLIST_LABEL="ai.openclaw.$INSTANCE_NAME"
|
|
359
356
|
PLIST_PATH="$HOME/Library/LaunchAgents/$PLIST_LABEL.plist"
|
|
@@ -374,42 +371,43 @@ EOP
|
|
|
374
371
|
fi
|
|
375
372
|
fi
|
|
376
373
|
|
|
377
|
-
#
|
|
374
|
+
# 定义可执行文件路径:优先使用全局 openclaw,否则用绝对路径 node
|
|
378
375
|
if command -v openclaw &> /dev/null; then
|
|
379
|
-
|
|
376
|
+
OPENCLAW_EXEC="openclaw"
|
|
380
377
|
else
|
|
381
|
-
|
|
378
|
+
OPENCLAW_EXEC="node $SCRIPT_DIR/dist/index.js"
|
|
382
379
|
fi
|
|
383
380
|
|
|
384
381
|
# 根据命令行参数执行对应操作
|
|
385
382
|
if [ $# -eq 0 ]; then
|
|
386
|
-
#
|
|
383
|
+
# 无参数:启动网关
|
|
387
384
|
GATEWAY_PORT=$(node -e "console.log(require('$OPENCLAW_CONFIG_PATH').gateway.port)")
|
|
388
|
-
echo "🚀 使用 $
|
|
389
|
-
exec $
|
|
385
|
+
echo "🚀 使用 $OPENCLAW_EXEC 启动 OpenClaw-$INSTANCE_NAME 网关..."
|
|
386
|
+
exec $OPENCLAW_EXEC gateway run --port "$GATEWAY_PORT"
|
|
390
387
|
else
|
|
391
388
|
if [ "$1" = "tui" ]; then
|
|
392
|
-
# TUI
|
|
393
|
-
echo "🚀
|
|
389
|
+
# TUI 必须在 workspace 目录下运行,以正确加载模板文件
|
|
390
|
+
echo "🚀 启动 OpenClaw-$INSTANCE_NAME TUI (workspace mode)..."
|
|
394
391
|
cd "$OPENCLAW_WORKSPACE"
|
|
395
|
-
|
|
392
|
+
# 使用绝对路径调用 node,避免相对路径问题
|
|
393
|
+
exec node "$SCRIPT_DIR/dist/index.js" tui
|
|
396
394
|
else
|
|
397
|
-
#
|
|
398
|
-
echo "🚀 使用 $
|
|
399
|
-
exec $
|
|
395
|
+
# 其他命令直接在实例目录执行
|
|
396
|
+
echo "🚀 使用 $OPENCLAW_EXEC 执行 OpenClaw-$INSTANCE_NAME 命令: $@"
|
|
397
|
+
exec $OPENCLAW_EXEC "$@"
|
|
400
398
|
fi
|
|
401
399
|
fi
|
|
402
400
|
EOF
|
|
401
|
+
|
|
403
402
|
chmod +x "${INSTANCE_DIR}/start.sh"
|
|
404
403
|
|
|
405
404
|
# --- 12. 执行拉起 ---
|
|
406
405
|
echo -e "${BLUE}⚡ 正在后台启动服务...${NC}"
|
|
407
|
-
# 使用完整路径启动,避免相对路径问题
|
|
408
406
|
nohup "${INSTANCE_DIR}/start.sh" > "${INSTANCE_DIR}/workspace/server.log" 2>&1 &
|
|
409
407
|
PID=$!
|
|
410
408
|
|
|
411
|
-
# 等待几秒检查进程是否存活,并验证端口监听
|
|
412
409
|
sleep 5
|
|
410
|
+
|
|
413
411
|
check_port() {
|
|
414
412
|
if command -v lsof &> /dev/null; then
|
|
415
413
|
lsof -i :$PORT -sTCP:LISTEN -t &> /dev/null
|
|
@@ -418,7 +416,7 @@ check_port() {
|
|
|
418
416
|
elif command -v curl &> /dev/null; then
|
|
419
417
|
curl --head --connect-timeout 1 http://localhost:$PORT &> /dev/null
|
|
420
418
|
else
|
|
421
|
-
return 0
|
|
419
|
+
return 0
|
|
422
420
|
fi
|
|
423
421
|
}
|
|
424
422
|
|
|
@@ -429,6 +427,44 @@ if kill -0 $PID 2>/dev/null; then
|
|
|
429
427
|
echo -e "🌐 本地网关: http://localhost:${PORT}"
|
|
430
428
|
echo -e "📄 实时日志: tail -f ${INSTANCE_DIR}/workspace/server.log"
|
|
431
429
|
echo -e "${GREEN}================================================${NC}"
|
|
430
|
+
|
|
431
|
+
# --- 交互式菜单 ---
|
|
432
|
+
if [ -t 0 ]; then
|
|
433
|
+
echo
|
|
434
|
+
echo -e "${BLUE}请选择下一步操作:${NC}"
|
|
435
|
+
echo "1) 启动 TUI (终端交互界面)"
|
|
436
|
+
echo "2) 打开 Web UI (浏览器)"
|
|
437
|
+
echo "3) 退出"
|
|
438
|
+
read -p "请输入数字 [1-3]: " choice
|
|
439
|
+
case $choice in
|
|
440
|
+
1)
|
|
441
|
+
echo -e "${YELLOW}启动 TUI...${NC}"
|
|
442
|
+
cd "$INSTANCE_DIR"
|
|
443
|
+
./start.sh tui
|
|
444
|
+
;;
|
|
445
|
+
2)
|
|
446
|
+
TOKEN=$(node -e "console.log(require('$INSTANCE_DIR/config/openclaw.json').gateway?.auth?.token || '')")
|
|
447
|
+
if [ -n "$TOKEN" ]; then
|
|
448
|
+
URL="http://localhost:$PORT/?token=$TOKEN"
|
|
449
|
+
echo -e "${GREEN}请在浏览器中打开: ${BLUE}$URL${NC}"
|
|
450
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
451
|
+
open "$URL"
|
|
452
|
+
elif command -v xdg-open &> /dev/null; then
|
|
453
|
+
xdg-open "$URL"
|
|
454
|
+
fi
|
|
455
|
+
else
|
|
456
|
+
echo -e "${RED}未找到 token,请手动查看配置文件。${NC}"
|
|
457
|
+
fi
|
|
458
|
+
;;
|
|
459
|
+
3)
|
|
460
|
+
echo "退出"
|
|
461
|
+
exit 0
|
|
462
|
+
;;
|
|
463
|
+
*)
|
|
464
|
+
echo "无效选择"
|
|
465
|
+
;;
|
|
466
|
+
esac
|
|
467
|
+
fi
|
|
432
468
|
else
|
|
433
469
|
echo -e "${YELLOW}⚠️ 进程存在但端口 ${PORT} 未监听(可能启动较慢或检查工具问题),请查看日志: ${INSTANCE_DIR}/workspace/server.log${NC}"
|
|
434
470
|
fi
|
package/scripts/install-maca.sh
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
# =================================================================
|
|
3
3
|
# OpenClaw 离线增强版部署脚本 (适配 bundledDependencies + 中国区镜像)
|
|
4
4
|
# 核心逻辑:修复权限 -> 固化环境 -> 本地 pnpm 安装 -> 实例初始化
|
|
5
|
+
# 新增:可选安装 Ollama 本地模型(用于截屏识图)
|
|
5
6
|
# =================================================================
|
|
6
7
|
|
|
7
8
|
set -e
|
|
@@ -150,6 +151,96 @@ if [ ! -d "$OPENCLAW_SOURCE_DIR" ]; then
|
|
|
150
151
|
fi
|
|
151
152
|
echo -e "${GREEN}✅ 源码路径验证通过${NC}"
|
|
152
153
|
|
|
154
|
+
# ==================== 8.5 可选安装本地模型(用于截屏识图)====================
|
|
155
|
+
echo
|
|
156
|
+
echo -e "${YELLOW}📷 是否安装本地模型用于截屏识图?(需要约6GB内存,模型:qwen2.5-vl:7b-instruct-q4_k_m)${NC}"
|
|
157
|
+
read -p "请输入 y/N: " install_model_choice
|
|
158
|
+
|
|
159
|
+
if [[ "$install_model_choice" == "y" || "$install_model_choice" == "Y" ]]; then
|
|
160
|
+
echo -e "${YELLOW}🔍 检查 Ollama 环境...${NC}"
|
|
161
|
+
|
|
162
|
+
# 设置国内镜像源(关键!)
|
|
163
|
+
# 使用 GitHub 镜像加速下载安装脚本和二进制文件
|
|
164
|
+
export GITHUB_MIRROR="https://ghproxy.com"
|
|
165
|
+
|
|
166
|
+
if ! command -v ollama &> /dev/null; then
|
|
167
|
+
echo -e "${YELLOW}未检测到 Ollama,正在从国内镜像安装 Ollama...${NC}"
|
|
168
|
+
|
|
169
|
+
# 方法1:使用官方安装脚本(通过镜像加速)
|
|
170
|
+
echo -e "${BLUE}尝试通过镜像加速安装...${NC}"
|
|
171
|
+
if curl -fsSL ${GITHUB_MIRROR}/https://ollama.com/install.sh | sh; then
|
|
172
|
+
echo -e "${GREEN}✅ Ollama 安装成功${NC}"
|
|
173
|
+
else
|
|
174
|
+
echo -e "${YELLOW}脚本安装失败,尝试直接下载二进制包...${NC}"
|
|
175
|
+
# 方法2:直接下载二进制包(适用于 Linux/macOS)
|
|
176
|
+
if [[ "$OS" == "Linux" ]]; then
|
|
177
|
+
wget ${GITHUB_MIRROR}/https://github.com/ollama/ollama/releases/latest/download/ollama-linux-amd64.tgz
|
|
178
|
+
sudo tar -C /usr -xzf ollama-linux-amd64.tgz
|
|
179
|
+
rm ollama-linux-amd64.tgz
|
|
180
|
+
elif [[ "$OS" == "Darwin" ]]; then
|
|
181
|
+
# macOS 用户建议直接访问官网下载,或使用 homebrew
|
|
182
|
+
echo -e "${YELLOW}macOS 用户请手动下载安装包:${NC}"
|
|
183
|
+
echo -e "${BLUE}访问 https://ollama.com/download 或使用镜像:${NC}"
|
|
184
|
+
echo -e "${BLUE}curl -L ${GITHUB_MIRROR}/https://ollama.com/download/Ollama-darwin.zip -o Ollama.zip${NC}"
|
|
185
|
+
echo -e "${YELLOW}安装完成后重新运行此脚本${NC}"
|
|
186
|
+
exit 1
|
|
187
|
+
fi
|
|
188
|
+
|
|
189
|
+
if command -v ollama &> /dev/null; then
|
|
190
|
+
echo -e "${GREEN}✅ Ollama 二进制安装成功${NC}"
|
|
191
|
+
else
|
|
192
|
+
echo -e "${RED}❌ Ollama 安装失败,请手动安装后重试。${NC}"
|
|
193
|
+
echo -e "${YELLOW}您可以访问 https://ollama.com 下载安装包。${NC}"
|
|
194
|
+
fi
|
|
195
|
+
fi
|
|
196
|
+
else
|
|
197
|
+
echo -e "${GREEN}✅ Ollama 已安装${NC}"
|
|
198
|
+
fi
|
|
199
|
+
|
|
200
|
+
# 再次检查 ollama 是否可用
|
|
201
|
+
if command -v ollama &> /dev/null; then
|
|
202
|
+
echo -e "${YELLOW}配置国内模型镜像源加速下载...${NC}"
|
|
203
|
+
|
|
204
|
+
# 配置模型下载镜像源
|
|
205
|
+
# 方法A:通过环境变量(临时生效)
|
|
206
|
+
export OLLAMA_MIRROR="https://ollama.modelscope.cn" # 魔搭社区镜像
|
|
207
|
+
|
|
208
|
+
# 方法B:创建配置文件(永久生效)
|
|
209
|
+
mkdir -p ~/.ollama
|
|
210
|
+
cat > ~/.ollama/config.json << EOF
|
|
211
|
+
{
|
|
212
|
+
"registry": {
|
|
213
|
+
"mirrors": {
|
|
214
|
+
"registry.ollama.ai": "https://ollama.modelscope.cn"
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
EOF
|
|
219
|
+
echo -e "${GREEN}✅ 镜像源配置完成${NC}"
|
|
220
|
+
|
|
221
|
+
echo -e "${YELLOW}正在拉取模型 qwen2.5-vl:7b-instruct-q4_k_m,这可能需要一些时间...${NC}"
|
|
222
|
+
echo -e "${BLUE}使用魔搭社区镜像加速下载...${NC}"
|
|
223
|
+
|
|
224
|
+
# 使用镜像源拉取模型(如果失败则尝试其他源)
|
|
225
|
+
if ollama pull modelscope.cn/qwen/Qwen2.5-7B-Instruct-GGUF; then
|
|
226
|
+
echo -e "${GREEN}✅ 模型拉取成功${NC}"
|
|
227
|
+
else
|
|
228
|
+
echo -e "${YELLOW}从魔搭拉取失败,尝试从官方源(已配置镜像)拉取...${NC}"
|
|
229
|
+
if ollama pull qwen2.5-vl:7b-instruct-q4_k_m; then
|
|
230
|
+
echo -e "${GREEN}✅ 模型拉取成功${NC}"
|
|
231
|
+
else
|
|
232
|
+
echo -e "${RED}❌ 模型拉取失败,您稍后可以手动运行以下命令重试:${NC}"
|
|
233
|
+
echo -e "${YELLOW}export OLLAMA_MIRROR=https://ollama.modelscope.cn${NC}"
|
|
234
|
+
echo -e "${YELLOW}ollama pull qwen2.5-vl:7b-instruct-q4_k_m${NC}"
|
|
235
|
+
fi
|
|
236
|
+
fi
|
|
237
|
+
else
|
|
238
|
+
echo -e "${YELLOW}⚠️ Ollama 不可用,跳过模型安装。${NC}"
|
|
239
|
+
fi
|
|
240
|
+
else
|
|
241
|
+
echo -e "${BLUE}跳过本地模型安装。${NC}"
|
|
242
|
+
fi
|
|
243
|
+
|
|
153
244
|
# ==================== 9. 自动化实例初始化 (直接调用 create-instance.sh) ====================
|
|
154
245
|
CREATE_SCRIPT="$OPENCLAW_SOURCE_DIR/scripts/create-instance.sh"
|
|
155
246
|
|