@neomei/agent-soul-framework 4.5.1 → 4.5.3

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/setup-wizard.sh DELETED
@@ -1,420 +0,0 @@
1
- #!/bin/bash
2
- #
3
- # 魂器配置向导 — 全新安装后的一站式配置程序
4
- # 引导用户完成环境变量、连接器配置和服务启动
5
- #
6
- set -e
7
-
8
- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
9
- USER_NAME="${SUDO_USER:-$USER}"
10
- HOME_DIR="$(getent passwd "$USER_NAME" | cut -d: -f6)"
11
-
12
- # 颜色
13
- RED='\033[0;31m'
14
- GREEN='\033[0;32m'
15
- YELLOW='\033[1;33m'
16
- BLUE='\033[0;34m'
17
- CYAN='\033[0;36m'
18
- NC='\033[0m'
19
-
20
- print_header() {
21
- echo ""
22
- echo -e "${CYAN}╔══════════════════════════════════════════════════════════════╗${NC}"
23
- echo -e "${CYAN}║${NC} 魂器 · 初始配置向导 ${CYAN}║${NC}"
24
- echo -e "${CYAN}╚══════════════════════════════════════════════════════════════╝${NC}"
25
- echo ""
26
- }
27
-
28
- print_step() {
29
- echo ""
30
- echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
31
- echo -e "${BLUE} 步骤 $1: $2${NC}"
32
- echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
33
- echo ""
34
- }
35
-
36
- print_success() { echo -e "${GREEN}✅${NC} $1"; }
37
- print_warning() { echo -e "${YELLOW}⚠️${NC} $1"; }
38
- print_error() { echo -e "${RED}❌${NC} $1"; }
39
- print_info() { echo -e "${BLUE}ℹ️${NC} $1"; }
40
-
41
- # 非交互模式检测
42
- NONINTERACTIVE="${NONINTERACTIVE:-0}"
43
-
44
- # 安全读取输入
45
- safe_read() {
46
- local prompt="$1"
47
- local var_name="$2"
48
- if [ "$NONINTERACTIVE" = "1" ]; then
49
- return 1
50
- fi
51
- if [ -t 0 ] || [ -e /dev/tty ]; then
52
- read -rp "$prompt" "$var_name" < /dev/tty
53
- else
54
- return 1
55
- fi
56
- }
57
-
58
- # 询问是否继续
59
- ask_continue() {
60
- local msg="$1"
61
- if [ "$NONINTERACTIVE" = "1" ]; then
62
- return 0
63
- fi
64
- local answer
65
- safe_read "$msg [Y/n]: " answer
66
- [[ ! "$answer" =~ ^[Nn]$ ]]
67
- }
68
-
69
- # ───────────────────────────────────────────────
70
- # 步骤 1: 环境检查
71
- # ───────────────────────────────────────────────
72
- step1_check_env() {
73
- print_step "1/5" "环境检查"
74
-
75
- local issues=0
76
-
77
- # 检查 Node.js
78
- if command -v node &>/dev/null; then
79
- NODE_VERSION=$(node -v | sed 's/v//')
80
- print_success "Node.js $NODE_VERSION"
81
- else
82
- print_error "Node.js 未安装(需要 ≥ 20)"
83
- issues=$((issues + 1))
84
- fi
85
-
86
- # 检查 opencode
87
- if command -v opencode &>/dev/null; then
88
- print_success "OpenCode 已安装"
89
- else
90
- print_warning "OpenCode 未找到,请运行: npm install -g opencode-ai"
91
- issues=$((issues + 1))
92
- fi
93
-
94
- # 检查 Python
95
- if command -v python3 &>/dev/null; then
96
- print_success "Python $(python3 --version 2>&1 | cut -d' ' -f2)"
97
- else
98
- print_warning "Python 未安装(心跳功能将不可用)"
99
- fi
100
-
101
- # 检查可选 channel 插件(飞书/企微,按需安装)
102
- if command -v opencode-feishu &>/dev/null; then
103
- print_success "飞书通道插件 (opencode-feishu)"
104
- else
105
- print_info "飞书通道插件未安装(可选),安装命令: npm install -g @neomei/opencode-feishu"
106
- fi
107
-
108
- if command -v opencode-qiwei &>/dev/null; then
109
- print_success "企微通道插件 (opencode-qiwei)"
110
- else
111
- print_info "企微通道插件未安装(可选),安装命令: npm install -g @neomei/opencode-qiwei"
112
- fi
113
-
114
- if command -v python3 &>/dev/null; then
115
- print_step "2/5" "环境变量配置"
116
-
117
- ENV_FILE="${HOME_DIR}/.hunqi/.env"
118
- mkdir -p "$(dirname "$ENV_FILE")"
119
-
120
- # 非交互模式: 如果已有 .env 就直接用,没有就创建一个空的
121
- if [ "$NONINTERACTIVE" = "1" ]; then
122
- if [ -f "$ENV_FILE" ] && [ -s "$ENV_FILE" ]; then
123
- print_success "使用现有 .env 配置"
124
- else
125
- echo "# 魂器环境变量配置" > "$ENV_FILE"
126
- echo "# 请手动填写 API Key 或使用 setup-wizard.sh 交互式配置" >> "$ENV_FILE"
127
- print_warning ".env 已创建(空),请在安装完成后手动配置 API Key"
128
- fi
129
- # 同步到项目目录
130
- if [ -f "$SCRIPT_DIR/.env" ]; then
131
- cp "$ENV_FILE" "$SCRIPT_DIR/.env"
132
- fi
133
- return 0
134
- fi
135
-
136
- # 如果已有 .env,询问是否覆盖
137
- if [ -f "$ENV_FILE" ] && [ -s "$ENV_FILE" ]; then
138
- if ! ask_continue "检测到已有的 .env 配置,是否重新配置"; then
139
- print_info "跳过 .env 配置,使用现有配置"
140
- return 0
141
- fi
142
- fi
143
-
144
- print_info "请填写以下 API Key(没有的可直接回车跳过)"
145
- echo ""
146
-
147
- local vars=()
148
-
149
- # DashScope API Key
150
- echo -e "${CYAN}阿里云百炼 (DashScope)${NC} — 用于文本嵌入和向量检索"
151
- echo " 获取地址: https://dashscope.aliyun.com/"
152
- local dashscope_key
153
- safe_read " DASHSCOPE_API_KEY: " dashscope_key
154
- [ -n "$dashscope_key" ] && vars+=("DASHSCOPE_API_KEY=$dashscope_key")
155
- echo ""
156
-
157
- # 写入 .env
158
- {
159
- echo "# 魂器环境变量配置"
160
- echo "# 生成时间: $(date '+%Y-%m-%d %H:%M:%S')"
161
- echo ""
162
- for v in "${vars[@]}"; do
163
- echo "$v"
164
- done
165
- } > "$ENV_FILE"
166
-
167
- # 同时同步到项目目录
168
- if [ -f "$SCRIPT_DIR/.env" ]; then
169
- cp "$ENV_FILE" "$SCRIPT_DIR/.env"
170
- fi
171
-
172
- print_success ".env 已保存到 $ENV_FILE"
173
- }
174
-
175
- # ───────────────────────────────────────────────
176
- # 步骤 3: 飞书配置
177
- # ───────────────────────────────────────────────
178
- step3_feishu() {
179
- print_step "3/5" "飞书通道(可选)"
180
-
181
- if ! command -v opencode-feishu &>/dev/null; then
182
- print_info "opencode-feishu 未安装,跳过飞书配置"
183
- print_info "如需飞书通道,安装命令: npm install -g @neomei/opencode-feishu"
184
- print_info "安装后运行: opencode-feishu setup"
185
- return 0
186
- fi
187
-
188
- local feishu_config="${HOME_DIR}/.config/opencode/feishu.json"
189
-
190
- # 非交互模式跳过(opencode-feishu setup 需要 tty 扫码)
191
- if [ "$NONINTERACTIVE" = "1" ]; then
192
- if [ -f "$feishu_config" ]; then
193
- print_success "飞书配置已存在"
194
- else
195
- print_info "非交互模式跳过飞书配置"
196
- print_info "请手动运行: opencode-feishu setup"
197
- fi
198
- return 0
199
- fi
200
-
201
- local setup_ran=0
202
-
203
- if [ -f "$feishu_config" ]; then
204
- print_success "飞书配置已存在"
205
- if ask_continue "是否重新配置飞书"; then
206
- echo ""
207
- opencode-feishu setup
208
- setup_ran=1
209
- else
210
- print_info "跳过飞书配置"
211
- fi
212
- else
213
- print_info "开始飞书配置向导..."
214
- echo " 将显示二维码,请用飞书 App 扫码"
215
- echo ""
216
- if ask_continue "是否现在配置飞书"; then
217
- opencode-feishu setup
218
- setup_ran=1
219
- else
220
- print_info "跳过飞书配置,稍后手动运行: opencode-feishu setup"
221
- fi
222
- fi
223
-
224
- # 扫码成功后,自动把凭证同步到 .env
225
- if [ "$setup_ran" = "1" ] && [ -f "$feishu_config" ]; then
226
- local fs_app_id fs_app_secret
227
- # 优先用 jq,否则用 sed 回退
228
- if command -v jq &>/dev/null; then
229
- fs_app_id=$(jq -r '.appId // empty' "$feishu_config" 2>/dev/null)
230
- fs_app_secret=$(jq -r '.appSecret // empty' "$feishu_config" 2>/dev/null)
231
- else
232
- fs_app_id=$(grep -o '"appId" *: *"[^"]*"' "$feishu_config" 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/')
233
- fs_app_secret=$(grep -o '"appSecret" *: *"[^"]*"' "$feishu_config" 2>/dev/null | sed 's/.*: *"\([^"]*\)".*/\1/')
234
- fi
235
-
236
- if [ -n "$fs_app_id" ] && [ -n "$fs_app_secret" ]; then
237
- ENV_FILE="${HOME_DIR}/.hunqi/.env"
238
- # 更新或追加 FEISHU_APP_ID / FEISHU_APP_SECRET
239
- for key_val in "FEISHU_APP_ID=$fs_app_id" "FEISHU_APP_SECRET=$fs_app_secret"; do
240
- key="${key_val%%=*}"
241
- if grep -q "^${key}=" "$ENV_FILE" 2>/dev/null; then
242
- sed -i "s|^${key}=.*|${key_val}|" "$ENV_FILE"
243
- elif grep -q "^#.*${key}" "$ENV_FILE" 2>/dev/null; then
244
- sed -i "s|^#.*${key}.*|${key_val}|" "$ENV_FILE"
245
- else
246
- echo "$key_val" >> "$ENV_FILE"
247
- fi
248
- done
249
- # 同步到项目目录
250
- if [ -f "$SCRIPT_DIR/.env" ]; then
251
- cp "$ENV_FILE" "$SCRIPT_DIR/.env"
252
- fi
253
- print_success "飞书凭证已自动同步到 .env"
254
- fi
255
- fi
256
-
257
- # 如果仍然没有 feishu.json(用户跳过了扫码),提示手动输入
258
- if [ ! -f "$feishu_config" ]; then
259
- echo ""
260
- print_info "未检测到飞书配置,可手动补录凭证到 .env:"
261
- echo " FEISHU_APP_ID=cli_xxxxxx"
262
- echo " FEISHU_APP_SECRET=xxxxxxxx"
263
- echo " 配置文件: ${HOME_DIR}/.hunqi/.env"
264
- fi
265
- }
266
-
267
- # ───────────────────────────────────────────────
268
- # 步骤 4: 企微配置
269
- # ───────────────────────────────────────────────
270
- step4_qiwei() {
271
- print_step "4/5" "企业微信通道(可选)"
272
-
273
- if ! command -v opencode-qiwei &>/dev/null; then
274
- print_info "opencode-qiwei 未安装,跳过企微配置"
275
- print_info "如需企微通道,安装命令: npm install -g @neomei/opencode-qiwei"
276
- print_info "安装后运行: opencode-qiwei setup"
277
- return 0
278
- fi
279
-
280
- local qiwei_config="${HOME_DIR}/.config/opencode/qiwei.json"
281
-
282
- # 非交互模式跳过
283
- if [ "$NONINTERACTIVE" = "1" ]; then
284
- if [ -f "$qiwei_config" ]; then
285
- print_success "企微配置已存在"
286
- else
287
- print_info "非交互模式跳过企微配置"
288
- print_info "请手动运行: opencode-qiwei setup"
289
- fi
290
- return 0
291
- fi
292
-
293
- if [ -f "$qiwei_config" ]; then
294
- print_success "企微配置已存在"
295
- if ask_continue "是否重新配置企微"; then
296
- echo ""
297
- opencode-qiwei setup
298
- else
299
- print_info "跳过企微配置"
300
- fi
301
- else
302
- if ask_continue "是否现在配置企微"; then
303
- opencode-qiwei setup
304
- else
305
- print_info "跳过企微配置,稍后手动运行: opencode-qiwei setup"
306
- fi
307
- fi
308
- }
309
-
310
- # ───────────────────────────────────────────────
311
- # 步骤 5: 验证和启动
312
- # ───────────────────────────────────────────────
313
- step5_verify_start() {
314
- print_step "5/5" "验证和启动"
315
-
316
- # 验证飞书
317
- if command -v opencode-feishu &>/dev/null; then
318
- echo ""
319
- print_info "检查飞书连接..."
320
- if opencode-feishu doctor 2>/dev/null; then
321
- print_success "飞书连接正常"
322
- else
323
- print_warning "飞书连接检查未通过,请检查配置"
324
- fi
325
- fi
326
-
327
- echo ""
328
- print_info "配置完成!"
329
- echo ""
330
- echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
331
- echo -e "${GREEN} 🎉 魂器初始配置完成!${NC}"
332
- echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
333
- echo ""
334
-
335
- # 启动选项
336
- if [ "$EUID" -eq 0 ] || sudo -n true 2>/dev/null; then
337
- if [ "$NONINTERACTIVE" = "1" ]; then
338
- # 非交互模式:自动启动 systemd
339
- echo ""
340
- print_info "自动启动 systemd 服务..."
341
- sudo systemctl start "hunqi-core@${USER_NAME}" 2>/dev/null || print_warning "hunqi-core 启动失败"
342
- sleep 3
343
- sudo systemctl start "channel-feishu@${USER_NAME}" 2>/dev/null || print_warning "channel-feishu 启动失败"
344
- echo ""
345
- print_success "服务已启动"
346
- echo " 查看状态: sudo systemctl status channel-feishu@${USER_NAME}"
347
- echo " 查看日志: sudo journalctl -u channel-feishu@${USER_NAME} -f"
348
- else
349
- echo -e "${CYAN}启动方式选择:${NC}"
350
- echo ""
351
- echo " 1) systemd 后台运行(推荐,支持开机自启)"
352
- echo " 2) 前台运行(适合调试)"
353
- echo " 3) 暂不启动"
354
- echo ""
355
-
356
- local choice
357
- safe_read " 请选择 [1]: " choice
358
- choice="${choice:-1}"
359
-
360
- case "$choice" in
361
- 1)
362
- echo ""
363
- print_info "启动 systemd 服务..."
364
- sudo systemctl start "hunqi-core@${USER_NAME}" 2>/dev/null || print_warning "hunqi-core 启动失败"
365
- sleep 3
366
- sudo systemctl start "channel-feishu@${USER_NAME}" 2>/dev/null || print_warning "channel-feishu 启动失败"
367
- echo ""
368
- print_success "服务已启动"
369
- echo " 查看状态: sudo systemctl status channel-feishu@${USER_NAME}"
370
- echo " 查看日志: sudo journalctl -u channel-feishu@${USER_NAME} -f"
371
- ;;
372
- 2)
373
- echo ""
374
- print_info "前台启动..."
375
- echo " 运行: cd $SCRIPT_DIR && hunqi start"
376
- ;;
377
- *)
378
- print_info "已跳过启动"
379
- echo ""
380
- echo " 后台启动: sudo systemctl start hunqi-core@${USER_NAME}"
381
- echo " 前台启动: cd $SCRIPT_DIR && hunqi start"
382
- ;;
383
- esac
384
- fi
385
- else
386
- echo " 前台启动: cd $SCRIPT_DIR && hunqi start"
387
- echo " 交互 TUI: cd $SCRIPT_DIR && hunqi interactive"
388
- fi
389
-
390
- echo ""
391
- echo " 其他常用命令:"
392
- echo " hunqi doctor # 系统诊断"
393
- echo " hunqi status # 查看状态"
394
- echo " opencode-feishu setup # 重新配置飞书"
395
- echo ""
396
- }
397
-
398
- # ═══════════════════════════════════════════════
399
- # 主程序
400
- # ═══════════════════════════════════════════════
401
-
402
- print_header
403
-
404
- # 如果不在项目目录,尝试自动定位
405
- if [ ! -f "$SCRIPT_DIR/package.json" ]; then
406
- if [ -f "${HOME_DIR}/.hunqi/agent-soul-framework/packages/agent-soul-framework/package.json" ]; then
407
- SCRIPT_DIR="${HOME_DIR}/.hunqi/agent-soul-framework/packages/agent-soul-framework"
408
- cd "$SCRIPT_DIR"
409
- print_info "自动定位到核心框架目录: $SCRIPT_DIR"
410
- else
411
- print_error "未找到魂器核心框架目录"
412
- exit 1
413
- fi
414
- fi
415
-
416
- step1_check_env
417
- step2_env_config
418
- step3_feishu
419
- step4_qiwei
420
- step5_verify_start
package/setup.sh DELETED
@@ -1,128 +0,0 @@
1
- #!/bin/bash
2
- # setup.sh - 魂器初始化脚本
3
- # 一键检查和修复 .opencode/opencode.json 配置,确保插件注册、模型配置完整
4
-
5
- set -e
6
-
7
- cd "$(dirname "$0")"
8
-
9
- OPENCODE_JSON=".opencode/opencode.json"
10
- OPENCODE_EXAMPLE=".opencode/opencode.json.example"
11
-
12
- echo "🚀 魂器初始化 (Agent Soul Framework Setup)"
13
- echo ""
14
-
15
- # ========== Step 1: 确保 opencode.json 存在 ==========
16
- if [ ! -f "$OPENCODE_JSON" ]; then
17
- echo "📄 $OPENCODE_JSON 不存在,从模板创建..."
18
- if [ -f "$OPENCODE_EXAMPLE" ]; then
19
- cp "$OPENCODE_EXAMPLE" "$OPENCODE_JSON"
20
- else
21
- echo "❌ 错误: $OPENCODE_EXAMPLE 也不存在"
22
- exit 1
23
- fi
24
- echo "✅ 已创建 $OPENCODE_JSON"
25
- echo "⚠️ 请编辑该文件填入你的 API key 和 provider 配置"
26
- echo ""
27
- fi
28
-
29
- # ========== Step 2: 用 Python 检查和修复 JSON 配置 ==========
30
- python3 << 'PYTHON_SCRIPT'
31
- import json
32
- import sys
33
-
34
- OPENCODE_JSON = ".opencode/opencode.json"
35
-
36
- with open(OPENCODE_JSON, "r") as f:
37
- content = f.read()
38
-
39
- try:
40
- config = json.loads(content)
41
- except json.JSONDecodeError as e:
42
- print(f"❌ {OPENCODE_JSON} JSON 格式错误: {e}")
43
- sys.exit(1)
44
-
45
- modified = False
46
-
47
- # --- 2.1 检查并添加 plugin 配置 ---
48
- if "plugin" not in config:
49
- config["plugin"] = ["./tools/read-plugin.js"]
50
- print("🔧 添加 plugin 配置: ./tools/read-plugin.js")
51
- modified = True
52
- else:
53
- plugins = config["plugin"]
54
- if isinstance(plugins, list):
55
- if "./tools/read-plugin.js" not in plugins:
56
- plugins.append("./tools/read-plugin.js")
57
- print("🔧 添加 plugin 配置: ./tools/read-plugin.js")
58
- modified = True
59
- else:
60
- print("✅ plugin 配置已存在")
61
- else:
62
- config["plugin"] = ["./tools/read-plugin.js"]
63
- print("🔧 修复 plugin 配置: ./tools/read-plugin.js")
64
- modified = True
65
-
66
- # --- 2.2 检查并添加 compaction 配置 ---
67
- if "compaction" not in config:
68
- config["compaction"] = {
69
- "auto": True,
70
- "prune": True,
71
- "tail_turns": 3,
72
- "preserve_recent_tokens": 8000,
73
- "reserved": 16384
74
- }
75
- print("🔧 添加 compaction 配置")
76
- modified = True
77
- else:
78
- print("✅ compaction 配置已存在")
79
-
80
- # --- 2.3 检查 model 是否已设置 ---
81
- if "model" not in config or not config["model"] or config["model"] == "your-default-model":
82
- print("⚠️ model 未配置,请在 {OPENCODE_JSON} 中设置默认模型")
83
- else:
84
- print(f"✅ 默认模型: {config['model']}")
85
-
86
- # --- 2.4 检查 provider 是否已设置 ---
87
- if "provider" not in config or not config["provider"]:
88
- print("⚠️ provider 未配置,请在 {OPENCODE_JSON} 中设置 API provider")
89
- else:
90
- providers = list(config["provider"].keys())
91
- print(f"✅ 已配置 providers: {', '.join(providers)}")
92
-
93
- # --- 2.5 检查模型是否有 attachment/modalities/limit 配置 ---
94
- if "provider" in config and isinstance(config["provider"], dict):
95
- for pname, pdata in config["provider"].items():
96
- if "models" in pdata and isinstance(pdata["models"], dict):
97
- for mname, mdata in pdata["models"].items():
98
- if isinstance(mdata, dict):
99
- missing = []
100
- if "attachment" not in mdata:
101
- missing.append("attachment")
102
- if "modalities" not in mdata:
103
- missing.append("modalities")
104
- if "limit" not in mdata:
105
- missing.append("limit")
106
- if missing:
107
- print(f"⚠️ provider '{pname}' 模型 '{mname}' 缺少配置: {', '.join(missing)}")
108
-
109
- # 保存修改
110
- if modified:
111
- with open(OPENCODE_JSON, "w") as f:
112
- json.dump(config, f, indent=2, ensure_ascii=False)
113
- f.write("\n")
114
- print("")
115
- print("✅ 配置已自动修复并保存")
116
- else:
117
- print("")
118
- print("✅ 配置检查通过,无需修改")
119
-
120
- PYTHON_SCRIPT
121
-
122
- echo ""
123
- echo "📋 初始化完成"
124
- echo ""
125
- echo "下一步:"
126
- echo " 1. 编辑 .opencode/opencode.json 填入 API key"
127
- echo " 2. 运行 ./hunqi.sh interactive 启动交互模式"
128
- echo ""