@neomei/agent-soul-framework 4.5.2 → 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/README.md +30 -19
- package/connectors/feishu/background.sh +2 -2
- package/connectors/feishu/core-start.sh +20 -10
- package/connectors/feishu/hooks/on-session-created.sh +1 -1
- package/connectors/feishu/hooks/on-session-idle.sh +1 -1
- package/connectors/feishu/model-failover.sh +15 -3
- package/connectors/feishu/restart-all.sh +5 -4
- package/connectors/feishu/restart-feishu.sh +1 -1
- package/connectors/feishu/restart-serve.sh +1 -1
- package/connectors/feishu/scripts/session-cleanup.sh +1 -1
- package/connectors/feishu/start.sh +1 -1
- package/connectors/feishu/stop.sh +3 -4
- package/connectors/feishu/systemd/install-systemd.sh +11 -2
- package/connectors/feishu/systemd/sleep-hooks/99-hunqi-resume.sh +1 -1
- package/connectors/feishu/watchdog.sh +1 -1
- package/dist/cli/hunqi.d.ts +1 -1
- package/dist/cli/hunqi.js +49 -200
- package/dist/cli/hunqi.js.map +1 -1
- package/heartbeat_wrapper.sh +1 -1
- package/hunqi.sh +1 -1
- package/install.sh +13 -280
- package/package.json +4 -4
- package/scripts/content-filter.js +3 -1
- package/scripts/health-check.sh +2 -2
- package/scripts/session-cleanup.sh +1 -1
- package/start-feishu-daemon.sh +2 -2
- package/start.sh +1 -1
- package/test.sh +1 -1
- package/uninstall.sh +13 -2
- package/verify.sh +1 -1
- package/setup-wizard.sh +0 -420
- package/setup.sh +0 -128
package/README.md
CHANGED
|
@@ -328,19 +328,35 @@ crontab -e
|
|
|
328
328
|
|
|
329
329
|
```
|
|
330
330
|
agent-soul-framework/
|
|
331
|
-
├── .opencode/ # OpenCode 引擎配置(prompt.md + opencode.json
|
|
331
|
+
├── .opencode/ # OpenCode 引擎配置(prompt.md + opencode.json + tools/)
|
|
332
332
|
├── soul/ # 灵魂定义 — 身份 · 性格 · 用户信息
|
|
333
333
|
│ ├── IDENTITY.md # 容貌 / 声音 / 身体
|
|
334
334
|
│ ├── SOUL.md # 核心原则 / 铁律 / 行为模式
|
|
335
|
-
│
|
|
335
|
+
│ ├── USER.md # 用户画像
|
|
336
|
+
│ └── HEARTBEAT.md # 心跳任务锚点定义
|
|
336
337
|
│
|
|
337
|
-
├──
|
|
338
|
+
├── plugin/ # OpenCode 灵魂注入插件(核心内置)
|
|
339
|
+
│ ├── index.js # 灵魂注入 + 对话保存
|
|
340
|
+
│ ├── manifest.json # OpenCode 插件清单
|
|
341
|
+
│ └── package.json
|
|
342
|
+
│
|
|
343
|
+
├── skills/ # 技能包(每个子目录一个独立技能,来自 agent-soul-skills)
|
|
338
344
|
│ ├── agent-photo/ # 拍照(即梦 API)
|
|
339
345
|
│ ├── agent-voice/ # 语音合成(TTS)
|
|
340
346
|
│ ├── agent-vision/ # 图片理解
|
|
341
347
|
│ ├── agent-hearing/ # 语音识别
|
|
348
|
+
│ ├── agent-video/ # 视频生成
|
|
349
|
+
│ ├── agent-gemini/ # Gemini 多模态
|
|
350
|
+
│ ├── agent-browser-core/ # 浏览器自动化
|
|
342
351
|
│ ├── agent-moltbook/ # Moltbook 社交
|
|
343
|
-
│
|
|
352
|
+
│ ├── aily-browser/ # 阿里 Aily 浏览器
|
|
353
|
+
│ ├── music-creator/ # Suno 音乐创作
|
|
354
|
+
│ ├── wechat-mp-assistant/# 公众号自动写作
|
|
355
|
+
│ ├── wechat-publisher/ # 公众号发布
|
|
356
|
+
│ ├── daily-digest/ # 每日摘要
|
|
357
|
+
│ ├── learning/ # 自主学习
|
|
358
|
+
│ ├── skill-creator/ # 技能自动创建
|
|
359
|
+
│ └── ... # 更多技能
|
|
344
360
|
│
|
|
345
361
|
├── memory/ # 持久化记忆
|
|
346
362
|
│ ├── short-term/ # SQLite 数据库(FTS5)
|
|
@@ -352,7 +368,7 @@ agent-soul-framework/
|
|
|
352
368
|
│ ├── growth/ # 成长记录
|
|
353
369
|
│ ├── intimacy/ # 亲密关系
|
|
354
370
|
│ ├── methodology/ # 方法论
|
|
355
|
-
│ ├── philosophy/
|
|
371
|
+
│ ├── philosophy/ # 哲学思考
|
|
356
372
|
│ ├── system/ # 系统机制
|
|
357
373
|
│ └── evolution/ # 进化方向
|
|
358
374
|
│
|
|
@@ -361,28 +377,23 @@ agent-soul-framework/
|
|
|
361
377
|
│ └── heartbeat_tasks.json# 任务定义
|
|
362
378
|
│
|
|
363
379
|
├── connectors/ # 外部连接器模板/文档
|
|
364
|
-
│
|
|
380
|
+
│ ├── feishu/ # 飞书 systemd 服务模板(opencode-feishu 插件安装后生效)
|
|
381
|
+
│ └── moltbook/ # Moltbook 连接器目录
|
|
365
382
|
│
|
|
366
|
-
├── scripts/ #
|
|
367
|
-
│ ├──
|
|
368
|
-
│ ├──
|
|
369
|
-
│
|
|
370
|
-
│ ├── memory_sync_and_index.py# 记忆同步 + 索引重建
|
|
371
|
-
│ ├── daily-knowledge-extract.py # 每日知识提取
|
|
372
|
-
│ ├── weekly-knowledge-sync.py # 每周知识整理
|
|
373
|
-
│ ├── monthly-knowledge-review.py # 月度知识审查
|
|
374
|
-
│ ├── skill_creator.py # 技能自主创建
|
|
375
|
-
│ ├── session_lineage.py # 会话血统追踪
|
|
376
|
-
│ ├── evolution_reflection.py # 进化反思
|
|
377
|
-
│ ├── write_wechat_article.py # 公众号自动写作
|
|
378
|
-
│ └── ...
|
|
383
|
+
├── scripts/ # 管理工具脚本(纯 TypeScript / Shell)
|
|
384
|
+
│ ├── content-filter.js # 内容过滤
|
|
385
|
+
│ ├── health-check.sh # 健康检查
|
|
386
|
+
│ └── session-cleanup.sh # 会话清理
|
|
379
387
|
│
|
|
380
388
|
├── AGENTS.md # Agent 行为准则(OpenCode 会话协议)
|
|
389
|
+
├── TOOLS.md # 工具调用规范
|
|
381
390
|
├── DREAMS.md # Agent 梦想
|
|
382
391
|
├── EVOLUTION.md # Agent 进化路线
|
|
383
392
|
└── README.md # 你在看这个
|
|
384
393
|
```
|
|
385
394
|
|
|
395
|
+
> 说明:核心框架已完全 TypeScript 化,历史 Python 管理脚本已迁移到 `@neomei/agent-soul-skills` 可选插件包,不影响核心运行。
|
|
396
|
+
|
|
386
397
|
---
|
|
387
398
|
|
|
388
399
|
## 🔧 核心命令速查
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/bin/bash
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
2
|
set -e
|
|
3
3
|
|
|
4
4
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
@@ -88,7 +88,7 @@ if [ "$HTTP_CODE" != "000" ]; then
|
|
|
88
88
|
echo " ✅ OpenCode server 已在运行 (HTTP $HTTP_CODE),跳过启动"
|
|
89
89
|
else
|
|
90
90
|
echo " 后台启动 OpenCode headless 服务器..."
|
|
91
|
-
|
|
91
|
+
nohup opencode serve --port "$OPENCODE_PORT" > /tmp/opencode-serve.log 2>&1 &
|
|
92
92
|
disown
|
|
93
93
|
sleep 3
|
|
94
94
|
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:$OPENCODE_PORT/session 2>/dev/null || true)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/bin/bash
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
2
|
#
|
|
3
3
|
# hunqi-core - 魂器核心启动脚本
|
|
4
4
|
# 只启动 OpenCode headless server,不启动任何连接器
|
|
@@ -21,15 +21,25 @@ echo ""
|
|
|
21
21
|
echo "启动 OpenCode headless 服务器 (port $OPENCODE_PORT)..."
|
|
22
22
|
|
|
23
23
|
# 等待端口释放
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
fi
|
|
24
|
+
# 跨平台端口检查 (lsof > ss > netstat)
|
|
25
|
+
port_in_use() {
|
|
26
|
+
if command -v lsof &>/dev/null; then
|
|
27
|
+
lsof -iTCP:"$1" -sTCP:LISTEN -t &>/dev/null && return 0 || return 1
|
|
28
|
+
elif command -v ss &>/dev/null; then
|
|
29
|
+
ss -tlnp 2>/dev/null | grep -q ":$1 " && return 0 || return 1
|
|
30
|
+
elif command -v netstat &>/dev/null; then
|
|
31
|
+
netstat -an 2>/dev/null | grep -q ":$1 .*LISTEN" && return 0 || return 1
|
|
32
|
+
fi
|
|
33
|
+
return 1
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
for i in $(seq 1 10); do
|
|
37
|
+
if ! port_in_use "$OPENCODE_PORT"; then
|
|
38
|
+
break
|
|
39
|
+
fi
|
|
40
|
+
echo " 等待端口 $OPENCODE_PORT 释放... ($i/10)"
|
|
41
|
+
sleep 1
|
|
42
|
+
done
|
|
33
43
|
|
|
34
44
|
# 启动 OpenCode serve
|
|
35
45
|
exec opencode serve --port "$OPENCODE_PORT"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/bin/bash
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
2
|
#
|
|
3
3
|
# 模型降级/恢复管理脚本
|
|
4
4
|
#
|
|
@@ -15,6 +15,18 @@ STATE_FILE="${HOME}/.config/opencode/model-failover.json"
|
|
|
15
15
|
PRIMARY_MODEL="deepseek/deepseek-v4-pro"
|
|
16
16
|
OPENCODE_PORT="${OPENCODE_PORT:-19876}"
|
|
17
17
|
|
|
18
|
+
# 跨平台端口 PID 获取
|
|
19
|
+
get_pid_on_port() {
|
|
20
|
+
local port="$1"
|
|
21
|
+
if command -v lsof &>/dev/null; then
|
|
22
|
+
lsof -iTCP:"$port" -sTCP:LISTEN -t 2>/dev/null | head -1
|
|
23
|
+
elif command -v ss &>/dev/null; then
|
|
24
|
+
ss -tlnp 2>/dev/null | grep ":$port " | sed -n 's/.*pid=\([0-9]*\).*/\1/p' | head -1
|
|
25
|
+
else
|
|
26
|
+
return 1
|
|
27
|
+
fi
|
|
28
|
+
}
|
|
29
|
+
|
|
18
30
|
mkdir -p "$(dirname "$STATE_FILE")"
|
|
19
31
|
|
|
20
32
|
# 读取当前降级状态
|
|
@@ -38,7 +50,7 @@ degrade() {
|
|
|
38
50
|
echo "Model degraded to: ${fallback_model}"
|
|
39
51
|
|
|
40
52
|
# 尝试重启 opencode serve(只杀指定端口的进程)
|
|
41
|
-
SERVE_PID=$(
|
|
53
|
+
SERVE_PID=$(get_pid_on_port "$OPENCODE_PORT")
|
|
42
54
|
if [ -n "$SERVE_PID" ]; then
|
|
43
55
|
echo "Restarting opencode serve (PID: $SERVE_PID) with fallback model..."
|
|
44
56
|
kill "$SERVE_PID" 2>/dev/null || true
|
|
@@ -56,7 +68,7 @@ restore() {
|
|
|
56
68
|
python3 -c "import json,sys; json.dump({'degraded':False,'model':'','since':0}, open(sys.argv[1],'w'))" "$STATE_FILE"
|
|
57
69
|
|
|
58
70
|
# 尝试重启 opencode serve 用主模型(只杀指定端口的进程)
|
|
59
|
-
SERVE_PID=$(
|
|
71
|
+
SERVE_PID=$(get_pid_on_port "$OPENCODE_PORT")
|
|
60
72
|
if [ -n "$SERVE_PID" ]; then
|
|
61
73
|
echo "Restarting opencode serve (PID: $SERVE_PID) with primary model..."
|
|
62
74
|
kill "$SERVE_PID" 2>/dev/null || true
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/bin/bash
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
2
|
#
|
|
3
3
|
# restart-all.sh — 重启全部服务(opencode serve + opencode-feishu)
|
|
4
4
|
# 顺序:先重启 serve(保留连接),再重启 feishu(先起后杀)
|
|
@@ -34,10 +34,11 @@ if [ -n "$FEISHU_NOTIFY_CHAT_ID" ]; then
|
|
|
34
34
|
APP_SECRET=$(node -e "console.log(require('$FEISHU_CONFIG').appSecret || '')" 2>/dev/null)
|
|
35
35
|
|
|
36
36
|
if [ -n "$APP_ID" ] && [ -n "$APP_SECRET" ]; then
|
|
37
|
-
# 获取 tenant_access_token
|
|
38
|
-
TOKEN_RESPONSE=$(
|
|
37
|
+
# 获取 tenant_access_token(JSON 体通过 stdin 传入,避免 secret 出现在 ps 中)
|
|
38
|
+
TOKEN_RESPONSE=$(printf '{"app_id":"%s","app_secret":"%s"}' "$APP_ID" "$APP_SECRET" | \
|
|
39
|
+
curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \
|
|
39
40
|
-H "Content-Type: application/json" \
|
|
40
|
-
-d
|
|
41
|
+
-d @- 2>/dev/null)
|
|
41
42
|
|
|
42
43
|
TOKEN=$(echo "$TOKEN_RESPONSE" | node -e "
|
|
43
44
|
let d = '';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/bin/bash
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
2
|
set -e
|
|
3
3
|
|
|
4
4
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
@@ -53,7 +53,7 @@ else
|
|
|
53
53
|
fi
|
|
54
54
|
|
|
55
55
|
# 只杀监听指定端口的 opencode serve,避免误杀其他实例
|
|
56
|
-
SERVE_PID=$(
|
|
56
|
+
SERVE_PID=$(get_pid_on_port "$PORT")
|
|
57
57
|
if [ -n "$SERVE_PID" ]; then
|
|
58
58
|
kill "$SERVE_PID" 2>/dev/null && echo "已停止 opencode serve (PID: $SERVE_PID, 端口: $PORT)"
|
|
59
59
|
else
|
|
@@ -62,8 +62,7 @@ fi
|
|
|
62
62
|
|
|
63
63
|
sleep 1
|
|
64
64
|
|
|
65
|
-
if
|
|
66
|
-
PID=$(ss -tlnp 2>/dev/null | grep ":${PORT} " | sed -n 's/.*pid=\([0-9]*\).*/\1/p')
|
|
65
|
+
if PID=$(get_pid_on_port "$PORT") && [ -n "$PID" ]; then
|
|
67
66
|
if [ -n "$PID" ]; then
|
|
68
67
|
PROC_NAME=$(ps -p "$PID" -o comm= 2>/dev/null || echo "unknown")
|
|
69
68
|
echo "端口 ${PORT} 仍被占用 (PID: $PID, $PROC_NAME),发送 SIGTERM..."
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/bin/bash
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
2
|
#
|
|
3
3
|
# 魂器 systemd 服务安装程序
|
|
4
4
|
# 核心+频道架构:hunqi-core + channel-feishu
|
|
@@ -50,8 +50,17 @@ if [ -z "$SUDO_USER" ] && [ "$USER" = "root" ]; then
|
|
|
50
50
|
fi
|
|
51
51
|
|
|
52
52
|
# 获取用户真正的家目录(不假设 /home/ 前缀)
|
|
53
|
-
|
|
53
|
+
# 跨平台获取用户家目录
|
|
54
|
+
HOME_DIR=""
|
|
55
|
+
if command -v getent &>/dev/null; then
|
|
56
|
+
HOME_DIR=$(getent passwd "$USER_NAME" 2>/dev/null | cut -d: -f6)
|
|
57
|
+
elif command -v dscl &>/dev/null; then
|
|
58
|
+
HOME_DIR=$(dscl . -read "/Users/$USER_NAME" NFSHomeDirectory 2>/dev/null | awk '{print $NF}')
|
|
59
|
+
fi
|
|
54
60
|
if [ -z "$HOME_DIR" ]; then
|
|
61
|
+
HOME_DIR=$(eval echo "~$USER_NAME" 2>/dev/null)
|
|
62
|
+
fi
|
|
63
|
+
if [ -z "$HOME_DIR" ] || [ ! -d "$HOME_DIR" ]; then
|
|
55
64
|
print_error "无法获取用户 $USER_NAME 的家目录"
|
|
56
65
|
exit 1
|
|
57
66
|
fi
|