@neomei/agent-soul-framework 4.5.2 → 4.5.4

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 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
- └── USER.md # 用户画像
335
+ ├── USER.md # 用户画像
336
+ │ └── HEARTBEAT.md # 心跳任务锚点定义
336
337
 
337
- ├── skills/ # 技能包(每个子目录一个独立技能)
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
- └── wechat-mp-assistant/# 公众号自动写作
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
- └── feishu/ # 飞书 systemd 服务模板(opencode-feishu 插件安装后生效)
380
+ ├── feishu/ # 飞书 systemd 服务模板(opencode-feishu 插件安装后生效)
381
+ │ └── moltbook/ # Moltbook 连接器目录
365
382
 
366
- ├── scripts/ # 管理工具脚本
367
- │ ├── memory_structured.py # 结构化记忆管理
368
- │ ├── memory_manager.py # 记忆保存/同步
369
- ├── memory_search.py # 统一记忆搜索
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
- setsid opencode serve --port "$OPENCODE_PORT" > /tmp/opencode-serve.log 2>&1 &
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
- if command -v ss &>/dev/null; then
25
- for i in $(seq 1 10); do
26
- if ! ss -tlnp | grep -q ":$OPENCODE_PORT "; then
27
- break
28
- fi
29
- echo " 等待端口 $OPENCODE_PORT 释放... ($i/10)"
30
- sleep 1
31
- done
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
  # on-session-created.sh — 新建 session 时注入灵魂文件(缓存优化版)
3
3
  # 环境变量: HOOK_SESSION_ID, HOOK_OPENCODE_URL
4
4
 
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  # on-session-idle.sh — session idle 时(上下文压缩后)重新注入灵魂(缓存优化版)
3
3
  # 环境变量: HOOK_SESSION_ID, HOOK_OPENCODE_URL
4
4
 
@@ -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=$(ss -tlnp 2>/dev/null | grep ":${OPENCODE_PORT} " | sed -n 's/.*pid=\([0-9]*\).*/\1/p')
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=$(ss -tlnp 2>/dev/null | grep ":${OPENCODE_PORT} " | sed -n 's/.*pid=\([0-9]*\).*/\1/p')
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=$(curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \
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 "{\"app_id\":\"$APP_ID\",\"app_secret\":\"$APP_SECRET\"}" 2>/dev/null)
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
  #
3
3
  # restart-feishu.sh — 重启 opencode-feishu(飞书连接器)
4
4
  # 策略:先起后杀 — 先启动新实例,再停止旧实例,避免飞书连接永久中断
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  #
3
3
  # restart-serve.sh — 重启 opencode serve(OpenCode 核心服务)
4
4
  # Usage: ./restart-serve.sh [port]
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  # session-cleanup.sh — 清理消息过多的飞书 session 映射
3
3
  # 当 session 消息数超过阈值时,从 feishu-sessions.json 中移除映射
4
4
  # 下次对话会自动创建新 session
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  #
3
3
  # hunqi-feishu - 魂器飞书连接器启动脚本
4
4
  # 只启动 opencode-feishu 插件,依赖 hunqi-core 提供的 OpenCode server
@@ -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=$(ss -tlnp 2>/dev/null | grep ":${PORT} " | sed -n 's/.*pid=\([0-9]*\).*/\1/p')
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 ss -tlnp 2>/dev/null | grep -q ":${PORT} "; then
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
- HOME_DIR=$(getent passwd "$USER_NAME" | cut -d: -f6)
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
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  # 魂器挂起/唤醒钩子 - 重启核心和所有频道
3
3
 
4
4
  case "$1" in
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/usr/bin/env bash
2
2
  #
3
3
  # 飞书连接器保活守护脚本 (v2 — 使用 opencode-feishu status --json)
4
4
  #
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * 魂器 CLI — @neomei/agent-soul-framework
3
3
  *
4
- * 用法: hunqi <command> [options]
4
+ * 用法: agent-soul-framework <command> [options]
5
5
  */
6
6
  export {};