每日备份 2026-06-10 12:57:13

This commit is contained in:
root-backup committed 2026-06-10 12:57:14 +08:00
1 parent fda2ccb8c2
commit 3d2e638c6a
244 files changed
+58890 -3

No files matched your search

+132
View File
@@ -0,0 +1,132 @@
#!/bin/bash
# ============================================================================
# AI学习脚本 - 使用 Python 解析 JSON
# ============================================================================
MINIMAX_API="https://api.minimaxi.com/v1/chat/completions"
MINIMAX_KEY="sk-cp-bJSl7-48u8Y07PXD_x8Wp21JiBgYul7iEO6ZWNK4FBAA4DWzj-U-K8-mN-Flak-O8cOtRegt5FYviSRfBw_noa14z0FkFYzczCPUa41opZsg5AGZ4s4uqL8"
ROBOT_NAME="${ROBOT_NAME:-守护者}"
ROBOT_TYPE="${ROBOT_TYPE:-guardian}"
LEARNING_DIR="/root/.openclaw/workspace/sleep-learning"
TIMESTAMP=$(date '+%Y%m%d-%H%M%S')
mkdir -p "$LEARNING_DIR"
# 调用 MiniMax(用 Python 解析)
call_minimax() {
local prompt="$1"
# 先替换换行符
prompt=$(echo "$prompt" | tr '\n' ' ')
python3 << PYEOF
import json, urllib.request, sys
data = json.dumps({
"model": "minimax-m2.1",
"messages": [
{"role": "system", "content": "你是${ROBOT_NAME}。"},
{"role": "user", "content": "${prompt}"}
],
"max_tokens": 2000,
"temperature": 0.7
}).encode()
req = urllib.request.Request(
"${MINIMAX_API}",
data=data,
headers={
"Content-Type": "application/json",
"Authorization": "Bearer ${MINIMAX_KEY}"
}
)
try:
with urllib.request.urlopen(req) as r:
resp = json.loads(r.read().decode())
content = resp["choices"][0]["message"]["content"]
# 清理内容
content = content.replace("\n", " ").strip()
print(content)
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
PYEOF
}
guardian_topics() {
cat << 'TOPICS'
【系统架构】🛡️ - OpenClaw深度配置、向量数据库、分布式系统
【故障排查】🔧 - 常见问题、排查方法、性能优化
【AI Agent深化】🤖 - SOUL.md、记忆系统、工具调用
【知识管理】📚 - 技术文档、经验总结、持续学习
TOPICS
}
qinglong_topics() {
cat << 'TOPICS'
【写作助手】✍️ - 神话素材、古典武侠、角色塑造
【股票投资】📈 - 宏观经济、行业研究、风险控制
【网络自动化】🌐 - 网页抓取、API调用、效率工具
【AI能力提升】🤖 - 记忆系统、提示词工程、工作流
TOPICS
}
get_topics() {
[ "$ROBOT_TYPE" = "qinglong" ] && qinglong_topics || guardian_topics
}
do_learning() {
local cycle=$1
local topic=$(get_topics | sed -n "$(( (cycle - 1) % 4 + 1 ))p")
echo "📖 周期 $cycle: 学习 $topic"
local content=$(call_minimax "你正在学习:${topic}。请深度学习并产出一份具体的学习笔记:1.核心知识点 2.实践方法 3.学到了什么 4.如何应用。直接输出内容。")
cat > "${LEARNING_DIR}/learning-${ROBOT_TYPE}-cycle${cycle}-${TIMESTAMP}.md" << MD
# ${ROBOT_NAME} 学习周期 $cycle - $(date)
## 主题: ${topic}
$content
MD
echo "✅ 学习笔记保存"
}
do_reflection() {
local cycle=$1
echo "💭 周期 $cycle: 深度反思"
local content=$(call_minimax "你刚完成了第${cycle}轮学习。请深度反思:1.学到了什么 2.理解程度 3.疑问 4.改进点。直接输出反思内容。")
cat > "${LEARNING_DIR}/reflection-${ROBOT_TYPE}-cycle${cycle}-${TIMESTAMP}.md" << MD
# ${ROBOT_NAME} 反思周期 $cycle - $(date)
$content
MD
echo "✅ 反思笔记保存"
}
do_summary() {
local cycle=$1
echo "📊 周期 $cycle: 深度总结"
local content=$(call_minimax "请深度总结你的学习成果:1.核心收获 2.如何应用 3.下次重点 4.理解提升。直接输出总结内容。")
cat > "${LEARNING_DIR}/summary-${ROBOT_TYPE}-cycle${cycle}-${TIMESTAMP}.md" << MD
# ${ROBOT_NAME} 总结周期 $cycle - $(date)
$content
MD
echo "✅ 总结笔记保存"
}
main() {
local cycle=${1:-1}
echo "========================================"
echo "🧠 ${ROBOT_NAME} AI学习 (周期 $cycle)"
echo "========================================"
do_learning $cycle && sleep 2
do_reflection $cycle && sleep 2
do_summary $cycle
echo ""
echo "✅ 周期 $cycle 完成"
}
main "$@"
+175
View File
@@ -0,0 +1,175 @@
#!/bin/bash
# ============================================================================
# 自动学习循环 - 持续改进系统
# ============================================================================
# 流程:学习 → 改进总结 → 验证 → 再次学习
# ============================================================================
MINIMAX_API="https://api.minimaxi.com/v1/chat/completions"
MINIMAX_KEY="sk-cp-bJSl7-48u8Y07PXD_x8Wp21JiBgYul7iEO6ZWNK4FBAA4DWzj-U-K8-mN-Flak-O8cOtRegt5FYviSRfBw_noa14z0FkFYzczCPUa41opZsg5AGZ4s4uqL8"
ROBOT_NAME="${ROBOT_NAME:-守护者}"
ROBOT_TYPE="${ROBOT_TYPE:-guardian}"
LEARNING_DIR="/root/.openclaw/workspace/sleep-learning"
LOG_DIR="/var/log/openclaw/sleep-learning/${ROBOT_NAME}"
TEMP_DIR="/tmp/ai-learning-${ROBOT_TYPE}"
TIMESTAMP=$(date '+%Y%m%d-%H%M%S')
mkdir -p "$LEARNING_DIR" "$LOG_DIR" "$TEMP_DIR"
# 调用 MiniMax
call_minimax() {
local system="$1"
local user="$2"
# 保存到临时文件
echo "$user" > "${TEMP_DIR}/prompt.txt"
python3 << PYEOF
import json, urllib.request, sys
with open("${TEMP_DIR}/prompt.txt", "r") as f:
user_content = f.read()
data = json.dumps({
"model": "minimax-m2.1",
"messages": [
{"role": "system", "content": "$system"},
{"role": "user", "content": user_content}
],
"max_tokens": 1500,
"temperature": 0.7
}).encode()
req = urllib.request.Request("${MINIMAX_API}", data=data,
headers={"Content-Type": "application/json", "Authorization": "Bearer ${MINIMAX_KEY}"})
try:
with urllib.request.urlopen(req) as r:
resp = json.loads(r.read().decode())
content = resp["choices"][0]["message"]["content"]
print(content.replace("\n", " "))
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
PYEOF
}
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "${LOG_DIR}/auto-learning.log"
}
# ============================================================================
# 阶段1: 学习
# ============================================================================
do_learn() {
local cycle=$1
local topic=$(get_topic $cycle)
log "📖 === 学习阶段 (周期 $cycle) ==="
local content=$(call_minimax "你是${ROBOT_NAME}。" \
"请深度学习【$topic】,产出一份具体的学习笔记:1.核心知识点(3-5条)2.实践方法(2-3条)3.如何应用(2条)。简洁输出,每点不超过30字。")
echo "$content" > "${LEARNING_DIR}/learn-${ROBOT_TYPE}-cycle${cycle}-${TIMESTAMP}.md"
log "✅ 学习完成"
}
# ============================================================================
# 阶段2: 改进总结
# ============================================================================
do_improve() {
local cycle=$1
log "💭 === 改进总结阶段 ==="
local content=$(call_minimax "你是${ROBOT_NAME}。" \
"根据刚才的学习内容,请深度反思:1.核心收获是什么?2.有什么不足/疑问?3.下次如何改进?4.需要深入学习的点?简洁输出。")
echo "$content" > "${LEARNING_DIR}/improve-${ROBOT_TYPE}-cycle${cycle}-${TIMESTAMP}.md"
log "✅ 改进总结完成"
}
# ============================================================================
# 阶段3: 验证
# ============================================================================
do_verify() {
local cycle=$1
local task=$(get_task $cycle)
log "🔍 === 验证阶段 ==="
local result=$(call_minimax "你是${ROBOT_NAME}。" \
"请完成这个任务来验证学习效果:$task。要求:用30字以内回答,直接输出答案。")
echo "$result" > "${LEARNING_DIR}/verify-${ROBOT_TYPE}-cycle${cycle}-${TIMESTAMP}.md"
log "✅ 验证完成: $result"
}
# ============================================================================
# 辅助函数
# ============================================================================
get_topic() {
local topics=(
"系统架构 - OpenClaw配置、向量数据库、分布式系统"
"故障排查 - 日志分析、性能优化、安全审计"
"AI Agent - SOUL.md、记忆系统、工具调用"
"知识管理 - 技术文档、经验总结、持续学习"
)
echo "${topics[$(( ($1 - 1) % 4 ))]}"
}
get_task() {
local tasks=(
"用一句话解释什么是向量数据库"
"列出3个常见的性能问题及解决方案"
"解释SOUL.md的作用"
"如何写好技术文档?"
)
echo "${tasks[$(( ($1 - 1) % 4 ))]}"
}
# ============================================================================
# 主循环
# ============================================================================
main() {
local max_cycles=${1:-3}
echo "╔════════════════════════════════════════════════════╗"
echo "║ 🔄 ${ROBOT_NAME} 自动学习循环 ║"
echo "║ 流程:学习 → 改进总结 → 验证 → 再次学习 ║"
echo "╚════════════════════════════════════════════════════╝"
echo ""
log "========================================"
log "开始自动学习循环 (最多 $max_cycles 轮)"
log "========================================"
local cycle=1
while [ $cycle -le $max_cycles ]; do
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🔄 周期 $cycle / $max_cycles"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
do_learn $cycle
sleep 2
do_improve $cycle
sleep 2
do_verify $cycle
cycle=$((cycle + 1))
[ $cycle -le $max_cycles ] && sleep 3
done
echo ""
echo "╔════════════════════════════════════════════════════╗"
echo "║ ✅ 自动学习循环完成! ║"
echo "╚════════════════════════════════════════════════════╝"
echo ""
echo "📊 成果位置: ${LEARNING_DIR}/"
}
main "$@"
+169
View File
@@ -0,0 +1,169 @@
#!/bin/bash
#===========================================
# 自动恢复机制脚本
# 监控关键进程,失败时自动重启
#===========================================
# 配置文件
CONFIG_FILE="/root/.openclaw/config/auto-recovery.conf"
LOG_FILE="/root/.openclaw/logs/auto-recovery.log"
ALERT_LOG="/root/.openclaw/logs/auto-recovery-alerts.log"
mkdir -p /root/.openclaw/logs
#===========================================
# 加载配置
#===========================================
load_config() {
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
else
# 默认配置
CHECK_INTERVAL=60
RESTART_DELAY=5
MAX_RESTART=3
fi
}
#===========================================
# 记录日志
#===========================================
log() {
local message=$1
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo "[$timestamp] $message" >> "$LOG_FILE"
}
#===========================================
# 检查进程状态
#===========================================
check_process() {
local process_name=$1
local restart_cmd=$2
if pgrep -f "$process_name" > /dev/null; then
echo "✅ $process_name: 运行中"
return 0
else
echo "❌ $process_name: 未运行"
log "进程 $process_name 未运行,准备重启..."
# 尝试重启
local restart_count=1
while [ $restart_count -le $MAX_RESTART ]; do
log "尝试重启 $process_name (第 $restart_count 次)..."
eval "$restart_cmd" >> "$LOG_FILE" 2>&1
sleep $RESTART_DELAY
if pgrep -f "$process_name" > /dev/null; then
log "✅ $process_name 重启成功"
echo "✅ $process_name: 已重启"
return 0
fi
restart_count=$((restart_count + 1))
done
log "❌ $process_name 重启失败"
echo "❌ $process_name: 重启失败"
# 发送告警
echo "[$(date)] [CRITICAL] $process_name 自动恢复失败" >> "$ALERT_LOG"
return 1
fi
}
#===========================================
# 检查服务端口
#===========================================
check_port() {
local name=$1
local port=$2
if curl -s --noproxy 127.0.0.1 --max-time 5 http://127.0.0.1:$port/ > /dev/null 2>&1; then
echo "✅ $name 端口 $port: 正常"
return 0
else
echo "❌ $name 端口 $port: 无响应"
return 1
fi
}
#===========================================
# 自动恢复主逻辑
#===========================================
auto_recovery() {
echo "=== 自动恢复检查 $(date '+%Y-%m-%d %H:%M:%S') ==="
log "开始自动恢复检查..."
local failed=0
# 1. 检查 Gateway
echo ""
echo "检查 Gateway..."
if ! check_process "openclaw-gateway" "openclaw gateway restart"; then
((failed++))
fi
# 2. 检查端口
echo ""
echo "检查端口..."
check_port "Gateway" "18789"
# 3. 检查关键 OpenClaw 进程
echo ""
echo "检查 OpenClaw 进程..."
check_process "openclaw-gateway" "openclaw gateway restart"
# 总结
echo ""
if [ $failed -eq 0 ]; then
echo "✅ 自动恢复检查完成 - 所有服务正常"
log "自动恢复检查完成 - 所有服务正常"
else
echo "⚠️ 自动恢复检查完成 - $failed 项需要关注"
log "自动恢复检查完成 - $failed 项需要关注"
fi
}
#===========================================
# 持续监控模式
#===========================================
monitor_loop() {
load_config
echo "=== 自动恢复监控启动 ==="
echo "检查间隔: ${CHECK_INTERVAL}秒"
echo "最大重启次数: $MAX_RESTART"
log "自动恢复监控启动..."
while true; do
auto_recovery
sleep $CHECK_INTERVAL
done
}
#===========================================
# 命令行接口
#===========================================
case "${1:-check}" in
check)
load_config
auto_recovery
;;
monitor)
monitor_loop
;;
list)
load_config
echo "=== 自动恢复配置 ==="
echo "检查间隔: ${CHECK_INTERVAL}s"
echo "重启延迟: ${RESTART_DELAY}s"
echo "最大重启次数: $MAX_RESTART"
;;
*)
echo "用法: $0 {check|monitor|list}"
;;
esac
+19
View File
@@ -0,0 +1,19 @@
#!/bin/bash
# 经验复盘自动化脚本
LOG_DIR="/root/.openclaw/logs"
DOCS_DIR="/root/.openclaw/logs"
DATE=$(date '+%Y-%m-%d')
# 1. 收集今日问题
echo "=== 自动复盘 - $DATE ===" > $DOCS_DIR/auto_retrospective_$DATE.md
# 2. 统计任务执行
echo "## 任务执行统计" >> $DOCS_DIR/auto_retrospective_$DATE.md
grep -c "✅" $LOG_DIR/*dododo.log 2>/dev/null >> $DOCS_DIR/auto_retrospective_$DATE.md
# 3. 检查错误
echo "## 错误统计" >> $DOCS_DIR/auto_retrospective_$DATE.md
grep -c "ERROR" $LOG_DIR/*dododo.log 2>/dev/null >> $DOCS_DIR/auto_retrospective_$DATE.md
echo "自动复盘完成: $DOCS_DIR/auto_retrospective_$DATE.md"
+85
View File
@@ -0,0 +1,85 @@
#!/bin/bash
# ============================================================================
# 后台学习脚本 - 启动 sub-agent 进行持续学习
# ============================================================================
# 启动青龙后台学习
start_qinglong_bg_learning() {
echo "[$(date)] 启动青龙后台学习..." >> /var/log/openclaw/sleep-learning/background.log
# 使用 nohup 后台运行,自动学习 10 轮
nohup /root/.openclaw/scripts/auto-learning.sh 10 > /tmp/qinglong-bg-learning.log 2>&1 &
QL_PID=$!
echo $QL_PID > /tmp/qinglong-bg-learning.pid
echo "青龙后台学习已启动 (PID: $QL_PID)"
}
# 启动守护者后台学习
start_guardian_bg_learning() {
echo "[$(date)] 启动守护者后台学习..." >> /var/log/openclaw/sleep-learning/background.log
nohup /root/.openclaw/scripts/auto-learning.sh 10 > /tmp/guardian-bg-learning.log 2>&1 &
GR_PID=$!
echo $GR_PID > /tmp/guardian-bg-learning.pid
echo "守护者后台学习已启动 (PID: $GR_PID)"
}
# 启动所有后台学习
start_all() {
start_qinglong_bg_learning
start_guardian_bg_learning
}
# 检查状态
status() {
echo "========================================"
echo "🔄 后台学习状态"
echo "========================================"
echo ""
if [ -f /tmp/qinglong-bg-learning.pid ]; then
QL_PID=$(cat /tmp/qinglong-bg-learning.pid)
if ps -p $QL_PID > /dev/null 2>&1; then
echo "🐉 青龙:运行中 (PID: $QL_PID)"
echo " 日志: /tmp/qinglong-bg-learning.log"
else
echo "🐉 青龙:已结束"
fi
else
echo "🐉 青龙:未启动"
fi
if [ -f /tmp/guardian-bg-learning.pid ]; then
GR_PID=$(cat /tmp/guardian-bg-learning.pid)
if ps -p $GR_PID > /dev/null 2>&1; then
echo "🛡️ 守护者:运行中 (PID: $GR_PID)"
echo " 日志: /tmp/guardian-bg-learning.log"
else
echo "🛡️ 守护者:已结束"
fi
else
echo "🛡️ 守护者:未启动"
fi
}
# 主程序
case "$1" in
start-qinglong)
start_qinglong_bg_learning
;;
start-guardian)
start_guardian_bg_learning
;;
start-all)
start_all
;;
status)
status
;;
*)
echo "用法: $0 {start-qinglong|start-guardian|start-all|status}"
exit 1
;;
esac
@@ -0,0 +1,38 @@
#!/bin/bash
# 检测 GitHub API 限额状态,触发限额时发送 Telegram 通知
FLAG_FILE="/root/.openclaw/workspace/seo/logs/rate_limit_flag.json"
TELEGRAM_TOKEN=$(grep -o '"token":"[^"]*"' /root/.openclaw/config.yml 2>/dev/null | head -1 | cut -d'"' -f4)
CHAT_ID="5117446326"
if [ ! -f "$FLAG_FILE" ]; then
exit 0
fi
# 读取限额信息
if command -v python3 &> /dev/null; then
INFO=$(python3 -c "
import json
with open('$FLAG_FILE') as f:
d = json.load(f)
print(f\"剩余: {d.get('remaining', '?')}/{d.get('limit', '?')}, 检测时间: {d.get('detected_at', '?')}\")
\" 2>/dev/null)
else
INFO=$(cat "$FLAG_FILE")
fi
# 发送 Telegram 消息
if [ -n "$TELEGRAM_TOKEN" ] && [ -n "$CHAT_ID" ]; then
MSG="⚠️ SEO进化猎手检测到 GitHub API 限额触发!
$INFO
请手动检查后恢复任务。"
curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_TOKEN/sendMessage" \
-d "chat_id=$CHAT_ID" \
-d "text=$MSG" \
> /dev/null 2>&1
fi
# 保留标志文件,等待人工干预
+19
View File
@@ -0,0 +1,19 @@
#!/bin/bash
# ============================================================================
# 清理过期会话锁
# 功能:删除超过10分钟的会话锁文件
# 频率:每10分钟运行
# ============================================================================
LOCK_DIR="/root/.openclaw/agents/main/sessions"
AGE_MINUTES=10
count=0
find "$LOCK_DIR" -name "*.lock" -type f -mmin +$AGE_MINUTES -delete 2>/dev/null
count=$(find "$LOCK_DIR" -name "*.lock" -type f -mmin +$AGE_MINUTES 2>/dev/null | wc -l)
if [ $count -gt 0 ]; then
echo "[$(date '+%Y-%m-%d %H:%M')] 清理了 $count 个过期锁文件"
else
echo "[$(date '+%Y-%m-%d %H:%M')] 无过期锁文件"
fi
+98
View File
@@ -0,0 +1,98 @@
#!/bin/bash
#
# OpenClaw 配置备份监控脚本
# 功能:监控 openclaw.json 变化,自动备份,最多保留10个版本
#
OPENCLAW_CONFIG="/root/.openclaw/openclaw.json"
BACKUP_DIR="/root/.openclaw/backups"
MAX_BACKUPS=10
CHECK_INTERVAL=60 # 每60秒检查一次
# 确保备份目录存在
mkdir -p "$BACKUP_DIR"
# 获取当前文件的md5
get_md5() {
md5sum "$OPENCLAW_CONFIG" 2>/dev/null | cut -d' ' -f1
}
# 记录日志
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# 备份函数
backup_config() {
local current_md5=$(get_md5)
local timestamp=$(date '+%Y-%m-%d_%H-%M-%S')
local backup_file="$BACKUP_DIR/openclaw.json.$timestamp.bak"
# 复制配置文件
cp "$OPENCLAW_CONFIG" "$backup_file"
log "已备份: $backup_file (md5: $current_md5)"
# 清理旧备份,保留最多10个
backup_count=$(ls -1 "$BACKUP_DIR"/openclaw.json.*.bak 2>/dev/null | wc -l)
if [ "$backup_count" -gt "$MAX_BACKUPS" ]; then
# 按修改时间删除最旧的备份
old_backups=$(ls -1t "$BACKUP_DIR"/openclaw.json.*.bak | tail -n +$((MAX_BACKUPS + 1)))
for old_backup in $old_backups; do
rm -f "$old_backup"
log "已删除旧备份: $old_backup"
done
fi
# 保存当前md5供下次对比
echo "$current_md5" > "$BACKUP_DIR/.last_md5"
}
# 主循环
main() {
log "配置备份监控启动..."
# 首次运行:备份当前配置
if [ -f "$OPENCLAW_CONFIG" ]; then
# 检查是否有上次记录的md5
if [ -f "$BACKUP_DIR/.last_md5" ]; then
last_md5=$(cat "$BACKUP_DIR/.last_md5")
current_md5=$(get_md5)
if [ "$last_md5" != "$current_md5" ]; then
log "检测到配置变化,首次备份..."
backup_config
else
log "配置无变化,跳过备份"
# 更新md5记录(确保文件存在)
get_md5 > "$BACKUP_DIR/.last_md5"
fi
else
log "首次运行,备份当前配置..."
backup_config
fi
else
log "错误: 配置文件不存在: $OPENCLAW_CONFIG"
exit 1
fi
# 持续监控循环
while true; do
sleep "$CHECK_INTERVAL"
if [ ! -f "$OPENCLAW_CONFIG" ]; then
log "错误: 配置文件丢失: $OPENCLAW_CONFIG"
sleep 60
continue
fi
current_md5=$(get_md5)
last_md5=$(cat "$BACKUP_DIR/.last_md5" 2>/dev/null)
if [ "$last_md5" != "$current_md5" ]; then
log "检测到配置变化,开始备份..."
backup_config
fi
done
}
main
+80
View File
@@ -0,0 +1,80 @@
#!/bin/bash
#
# 每日故障报告生成脚本
# 用途: 每天生成故障统计和工作总结
#
REPORT_FILE="/var/log/openclaw/daily-report.log"
ALERT_LOG="/var/log/openclaw-monitor/alerts.log"
DATE=$(date +%Y-%m-%d)
echo "========================================" >> "$REPORT_FILE"
echo "每日故障报告 - $DATE" >> "$REPORT_FILE"
echo "========================================" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
# 1. 故障统计 (修复 grep -c 多行问题)
echo "【故障统计】" >> "$REPORT_FILE"
echo "---------------------------" >> "$REPORT_FILE"
CRITICAL=$(grep "$DATE.*CRITICAL" "$ALERT_LOG" 2>/dev/null | wc -l || echo "0")
ALERT=$(grep "$DATE.*ALERT" "$ALERT_LOG" 2>/dev/null | wc -l || echo "0")
AUTO=$(grep "$DATE.*AUTO" "$ALERT_LOG" 2>/dev/null | wc -l || echo "0")
echo "CRITICAL: $CRITICAL 条" >> "$REPORT_FILE"
echo "ALERT: $ALERT 条" >> "$REPORT_FILE"
echo "AUTO: $AUTO 条" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
# 2. 系统状态
echo "【系统状态】" >> "$REPORT_FILE"
echo "---------------------------" >> "$REPORT_FILE"
if pgrep -f "openclaw-gateway" > /dev/null; then
echo "Gateway: 运行中" >> "$REPORT_FILE"
else
echo "Gateway: 未运行" >> "$REPORT_FILE"
fi
MEM_USAGE=$(free -h | grep Mem | awk '{print $3 "/" $2}')
echo "内存: $MEM_USAGE" >> "$REPORT_FILE"
DISK_USAGE=$(df -h / | tail -1 | awk '{print $5 " used"}')
echo "磁盘: $DISK_USAGE" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
# 3. 记忆系统状态
echo "【记忆系统】" >> "$REPORT_FILE"
echo "---------------------------" >> "$REPORT_FILE"
DB="/root/.openclaw/workspace/memory/memory.db"
if [ -f "$DB" ]; then
USER_MEM=$(sqlite3 "$DB" "SELECT COUNT(*) FROM memories WHERE layer='user'" 2>/dev/null || echo "0")
SESSION_MEM=$(sqlite3 "$DB" "SELECT COUNT(*) FROM memories WHERE layer='session'" 2>/dev/null || echo "0")
AGENT_MEM=$(sqlite3 "$DB" "SELECT COUNT(*) FROM memories WHERE layer='agent'" 2>/dev/null || echo "0")
INSIGHTS=$(sqlite3 "$DB" "SELECT COUNT(*) FROM insights" 2>/dev/null || echo "0")
echo "User Memory: $USER_MEM 条" >> "$REPORT_FILE"
echo "Session Memory: $SESSION_MEM 条" >> "$REPORT_FILE"
echo "Agent Memory: $AGENT_MEM 条" >> "$REPORT_FILE"
echo "Insights: $INSIGHTS 条" >> "$REPORT_FILE"
fi
echo "" >> "$REPORT_FILE"
# 4. 计划任务状态
echo "【计划任务】" >> "$REPORT_FILE"
echo "---------------------------" >> "$REPORT_FILE"
openclaw cron list 2>/dev/null | grep -E "ok|idle" | head -5 >> "$REPORT_FILE" || echo "无任务" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
# 5. 总结
echo "【总结】" >> "$REPORT_FILE"
echo "---------------------------" >> "$REPORT_FILE"
TOTAL=$((CRITICAL + ALERT + AUTO))
if [ "$TOTAL" -lt 10 ]; then
echo "系统运行正常,故障较少。" >> "$REPORT_FILE"
elif [ "$TOTAL" -lt 50 ]; then
echo "系统运行一般,存在一定数量的告警。" >> "$REPORT_FILE"
else
echo "系统运行需关注,故障数量较多。" >> "$REPORT_FILE"
fi
echo "" >> "$REPORT_FILE"
echo "报告生成完成: $REPORT_FILE"
+196
View File
@@ -0,0 +1,196 @@
#!/bin/bash
# ============================================================================
# 极简灾难恢复备份系统
# ============================================================================
# 设计目标:保证能有限度恢复系统,非数据同步
# 设计原则:最低频率 + 最少数据 + 最小负担
# ============================================================================
BACKUP_DIR="/root/.openclaw/backups"
LOG_FILE="${BACKUP_DIR}/backup.log"
mkdir -p "${BACKUP_DIR}"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
echo "$1"
}
# ============================================================================
# 极简备份:只备份重建系统的最小集合
# ============================================================================
minimal_backup() {
log "=== 极简灾难备份开始 ==="
echo "╔════════════════════════════════════════════════════╗"
echo "║ 极简灾难恢复备份系统 ║"
echo "╚════════════════════════════════════════════════════╝"
echo ""
echo "设计目标:有限度恢复系统,非数据同步"
echo ""
local date=$(date '+%Y%m%d')
local backup_path="${BACKUP_DIR}/${date}"
mkdir -p "$backup_path"
# P0: 重建系统的绝对最小集合
echo "1️⃣ 核心配置 (P0)..."
# openclaw.json - 系统配置
cp -p /root/.openclaw/openclaw.json "${backup_path}/" 2>/dev/null
echo " ✅ openclaw.json"
# identity/ - 人格配置
cp -rp /root/.openclaw/identity/ "${backup_path}/" 2>/dev/null
echo " ✅ identity/"
# AGENTS.md - 人格注入
cp -p /root/.openclaw/workspace/AGENTS.md "${backup_path}/" 2>/dev/null
echo " ✅ AGENTS.md"
# P1: 可重建但有价值的数据(每周日备份)
echo ""
echo "2️⃣ 可选数据 (P1 - 仅周日)..."
if [ "$(date '+%u')" -eq 7 ]; then
# memory.sqlite - 记忆(5MB,可重建但有价值)
cp -p /root/.openclaw/memory/main.sqlite "${backup_path}/" 2>/dev/null
echo " ✅ memory.sqlite (周日)"
# sleep-learning/ - 学习记录(可重建,但保留有好处)
cp -rp /root/.openclaw/workspace/sleep-learning/ "${backup_path}/" 2>/dev/null
echo " ✅ sleep-learning (周日)"
else
echo " ⏭️ 跳过 (非周日)"
fi
# P2: 完全不备份
# - 会话文件:Gateway 可自动重建
# - 日志文件:可重建
echo ""
echo "3️⃣ 明确不备份 (P2)"
echo " ⏭️ 会话文件 - Gateway 自动重建"
echo " ⏭️ 日志文件 - 可重建"
echo " ⏭️ 临时文件 - 无需备份"
# 清理:只保留最近2周 + 每月1个
cleanup
log "=== 备份完成 ==="
echo ""
echo "✅ 极简备份完成"
echo ""
echo "📦 本次备份: $(du -sh "${backup_path}" | cut -f1)"
}
# ============================================================================
# 清理旧备份(极简策略)
# ============================================================================
cleanup() {
echo ""
echo "🧹 清理旧备份..."
# 保留最近14天
find "${BACKUP_DIR}" -maxdepth 1 -type d -name "20*" -mtime +14 -exec rm -rf {} \; 2>/dev/null
# 保留每月1个
ls -d "${BACKUP_DIR}"/20* 2>/dev/null | while read d; do
local day=$(basename "$d" | cut -c7) # 获取星期几
if [ "$day" = "0" ]; then
# 周日,保留
:
elif [ ! -d "$(dirname "$d")/$(basename "$d" | cut -c1-6)01" ]; then
# 月初且本月还没有备份
:
else
# 平日且不是本月第一个周日,删除
rm -rf "$d" 2>/dev/null
fi
done
echo " ✅ 清理完成 (保留14天 + 每月1个)"
}
# ============================================================================
# 快速恢复(极简)
# ============================================================================
quick_restore() {
local backup_path=$(ls -dt "${BACKUP_DIR}"/20* 2>/dev/null | head -1)
if [ -z "$backup_path" ]; then
echo "❌ 无备份可恢复"
return 1
fi
echo "⚠️ 快速恢复模式"
echo " 备份源: ${backup_path}"
echo ""
echo "将恢复:"
echo " 1. openclaw.json → 系统配置"
echo " 2. identity/* → 人格配置"
echo " 3. AGENTS.md → 人格注入"
if [ -f "${backup_path}/memory.sqlite" ]; then
echo " 4. memory.sqlite → 记忆"
fi
if [ -d "${backup_path}/sleep-learning" ]; then
echo " 5. sleep-learning/ → 学习记录"
fi
echo ""
echo "用法:"
echo " $0 restore config # 仅配置"
echo " $0 restore all # 全部"
}
# ============================================================================
# 状态查询
# ============================================================================
status() {
echo ""
echo "📊 灾难备份状态..."
local backup_count=$(ls -d "${BACKUP_DIR}"/20* 2>/dev/null | wc -l)
local latest=$(ls -dt "${BACKUP_DIR}"/20* 2>/dev/null | head -1)
if [ -n "$latest" ]; then
local size=$(du -sh "$latest" 2>/dev/null | cut -f1)
echo " ✅ 最新备份: ${latest##*/} (${size})"
echo " ✅ 备份数量: ${backup_count} 个"
echo " ✅ 备份总大小: $(du -sh "${BACKUP_DIR}" | cut -f1)"
else
echo " ⚠️ 无备份"
fi
echo ""
echo "📋 设计原则:"
echo " • 目标: 有限度恢复系统"
echo " • 频率: 每周1次"
echo " • 数据: 最少集合"
echo " • 保留: 14天 + 每月1个"
}
# ============================================================================
main() {
case "$1" in
backup)
minimal_backup
status
;;
status)
status
;;
restore)
quick_restore
;;
*)
echo "用法: $0 {backup|status|restore}"
echo ""
echo "极简灾难恢复备份系统"
echo ""
echo " backup - 执行备份 (每周日)"
echo " status - 查看状态"
echo " restore - 紧急恢复"
echo ""
echo "设计目标: 有限度恢复,非数据同步"
esac
}
main "$@"
+53
View File
@@ -0,0 +1,53 @@
#!/bin/bash
# dododo 服务: 支持并发执行
# 修复版: 智能等待,不再疯狂重启
LOG_FILE="/var/log/openclaw/dododo.log"
LOCK_FILE="/tmp/dododo_service.lock"
# 避免重复启动
if [ -f "$LOCK_FILE" ]; then
PID=$(cat "$LOCK_FILE")
if kill -0 "$PID" 2>/dev/null; then
echo "$(date) - dododo 已在运行 (PID: $PID)"
exit 1
fi
fi
echo $$ > "$LOCK_FILE"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> $LOG_FILE
}
log "========== dododo_service 启动 =========="
while true; do
# 检查是否应该运行
CURRENT_MIN=$(date '+%M')
CURRENT_HOUR=$(date '+%H')
# 只在每小时的 02-55 分运行
if [ "$CURRENT_MIN" -ge 2 ] && [ "$CURRENT_MIN" -lt 55 ]; then
log "========== $CURRENT_HOUR:$CURRENT_MIN - dododo.py 启动 =========="
cd /root/.openclaw/workspace && python3 dododo.py --auto --wait 30 --stop-minute 55 --workers 3 2>&1 | while read line; do
log "$line"
done
EXIT_CODE=$?
log "dododo.py 退出码: $EXIT_CODE"
else:
# 不在运行时间段,等待到下个02分
if [ "$CURRENT_MIN" -lt 2 ]; then
WAIT_MIN=$((2 - CURRENT_MIN))
else
WAIT_MIN=$((60 - CURRENT_MIN + 2))
fi
WAIT_SEC=$((WAIT_MIN * 60))
log "不在运行时间 ($CURRENT_HOUR:$CURRENT_MIN),等待 ${WAIT_MIN} 分钟..."
sleep $WAIT_SEC
fi
# 休息一下再检查,避免CPU空转
sleep 10
done
+154
View File
@@ -0,0 +1,154 @@
#!/bin/bash
# ============================================
# GitHub Intelligence Monitor v1.0
# 功能:主动监控GitHub榜单,寻找进化机会
# 监控范围:Trending + AI/Agent + 自动化 + Skills
# ============================================
set -e
PROXY="http://192.168.0.66:7890"
OUT_DIR="/root/.openclaw/workspace/github-intel"
REPORT="$OUT_DIR/report-$(date '+%Y%m%d').md"
PREVIOUS="$OUT_DIR/previous-projects.txt"
CURRENT="$OUT_DIR/current-projects.txt"
# 颜色
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
log() { echo -e "${BLUE}[Intel]${NC} $(date '+%H:%M:%S') $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $(date '+%H:%M:%S') $1"; }
info() { echo -e "${GREEN}[INFO]${NC} $(date '+%H:%M:%S') $1"; }
mkdir -p "$OUT_DIR"
# 1. 获取Trending页面
fetch_trending() {
log "正在获取 GitHub Trending..."
local content=$(curl -s --proxy "$PROXY" -A "Mozilla/5.0" "https://github.com/trending" | grep -oP 'href="/[a-zA-Z0-9_-]+/[a-zA-Z0-9_.-]+"' | grep -oP '(?<="\/)[^"]+' | grep -v 'trending\|developers\|sponsors\|apps' | head -30)
echo "$content" > "$CURRENT"
}
# 2. 对比差异(新增项目)
find_new_projects() {
if [ ! -f "$PREVIOUS" ]; then
touch "$PREVIOUS"
log "首次运行,建立历史数据"
return
fi
# 找出新增项目
comm -13 <(sort "$PREVIOUS") <(sort "$CURRENT") > "$OUT_DIR/new-projects.txt" 2>/dev/null || true
local count=$(wc -l < "$OUT_DIR/new-projects.txt" 2>/dev/null | grep -oP '^\d+' || echo 0)
log "发现 $count 个新项目"
}
# 3. 获取项目详情
get_project_details() {
local project="$1"
local api_url="https://api.github.com/repos/$project"
curl -s --proxy "$PROXY" -A "Mozilla/5.0" "$api_url" 2>/dev/null || echo "{}"
}
# 4. 评估进化价值
evaluate_evolution() {
local project="$1"
local details=$(get_project_details "$project")
local stars=$(echo "$details" | grep -oP '"stargazers_count":\d+' | head -1 | grep -oP '\d+' || echo 0)
local desc=$(echo "$details" | grep -oP '"description":"[^"]*"' | head -1 | sed 's/"description":"//;s/"$//' || echo "")
local lang=$(echo "$details" | grep -oP '"language":"[^"]*"' | head -1 | sed 's/"language":"//;s/"$//' || echo "")
# 进化关键词
local keywords="agent|skill|automation|browser|playwright|puppeteer|cli|tool|openclaw|claude|gpt|llm|ai|copilot"
local is_evolution=$(echo "$project $desc" | grep -iE "$keywords" || echo "")
if [ -n "$is_evolution" ] && [ "$stars" -gt 500 ]; then
echo "⭐ EVOLUTION_CANDIDATE: $project (⭐$stars) - $desc"
echo " 语言: $lang"
echo " 链接: https://github.com/$project"
echo ""
fi
}
# 5. 生成报告
generate_report() {
local new_count=$(wc -l < "$OUT_DIR/new-projects.txt" | awk '{print $1}' 2>/dev/null || echo 0)
{
echo "# GitHub Intelligence Report"
echo "生成时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo ""
echo "## 新增项目 ($new_count 个)"
echo ""
if [ -f "$OUT_DIR/new-projects.txt" ]; then
while IFS= read -r project; do
[ -z "$project" ] && continue
evaluate_evolution "$project"
done < "$OUT_DIR/new-projects.txt"
fi
echo ""
echo "## Trending Top 10"
echo ""
if [ -f "$CURRENT" ]; then
head -10 "$CURRENT" | while read -r project; do
[ -z "$project" ] && continue
evaluate_evolution "$project"
done
fi
echo ""
echo "## 进化建议"
echo ""
# 分析新增和热门项目中可能的进化机会
local candidates=$(grep -c "EVOLUTION_CANDIDATE" "$OUT_DIR/evolution-candidates.txt" 2>/dev/null || echo 0)
if [ "$candidates" -gt 0 ]; then
echo "发现 $candidates 个潜在进化目标,详见上方列表"
else
echo "本期无重大进化机会"
fi
} > "$REPORT"
info "报告已生成: $REPORT"
}
# 主流程
main() {
log "========== GitHub Intelligence Monitor =========="
fetch_trending
find_new_projects
# 生成候选列表
rm -f "$OUT_DIR/evolution-candidates.txt"
touch "$OUT_DIR/evolution-candidates.txt"
if [ -f "$CURRENT" ]; then
while IFS= read -r project; do
[ -z "$project" ] && continue
result=$(evaluate_evolution "$project")
if echo "$result" | grep -q "EVOLUTION_CANDIDATE"; then
echo "$result" >> "$OUT_DIR/evolution-candidates.txt"
fi
done < "$CURRENT"
fi
generate_report
# 更新历史
cp "$CURRENT" "$PREVIOUS"
log "========== 监控完成 =========="
# 输出摘要
local candidate_count=$(wc -l < "$OUT_DIR/evolution-candidates.txt" 2>/dev/null || echo 0)
if [ "$candidate_count" -gt 0 ]; then
echo ""
warn "发现 $candidate_count 个进化候选!"
cat "$OUT_DIR/evolution-candidates.txt"
fi
}
main "$@"
+413
View File
@@ -0,0 +1,413 @@
#!/bin/bash
# 守护者系统全面健康检查 v2.0
# 改进:自动修复 + 重试验证
#set -e
# 配置
PROXY="http://192.168.0.66:7890"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
LOG_FILE="/root/.openclaw/logs/health-check/health-$(date '+%Y%m%d').log"
OVERALL_SCORE=0
MAX_RETRIES=10
AUTO_REPAIRED_COUNT=0
ISSUE_COUNT=0
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"; }
log_section() { echo ""; echo "╔════════════════════════════════════════════════════════════╗"; echo "║ $1 ║"; echo "╚════════════════════════════════════════════════════════════╝"; }
log_item() { echo " $1 $2"; echo " $1 $2" >> "$LOG_FILE"; }
log_info() { echo " ℹ️ $1"; echo " ℹ️ $1" >> "$LOG_FILE"; }
add_issue() { echo "• $2" | tee -a "$LOG_FILE"; }
# 颜色
RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m'
# ==================== 主程序 ====================
main() {
mkdir -p "$(dirname "$LOG_FILE")"
log "========== 守护者系统健康检查开始 =========="
# 重试验证
local retry_count=0
while [ $retry_count -lt $MAX_RETRIES ]; do
((retry_count++))
echo ""
echo "═══════════════════════════════════════════════════════════"
echo " 第 $retry_count/$MAX_RETRIES 次检查"
echo "═══════════════════════════════════════════════════════════"
# 执行所有检查
check_hardware
check_system_load
check_memory
check_gateway
check_cron
check_learning
check_trading
check_websites
# 检查问题
if [ "$ISSUE_COUNT" -gt 0 ]; then
auto_repair
if [ $AUTO_REPAIRED_COUNT -gt 0 ]; then
echo ""
echo "🔄 等待验证修复结果..."
sleep 5
continue # 重新检查
fi
fi
break # 没有问题,退出
done
generate_reports
send_telegram_alert
log "========== 健康检查完成 =========="
}
# ==================== 1. 硬件状态 ====================
check_hardware() {
log_section "1. 硬件状态"
echo ""
# CPU
local cpu_model=$(grep "model name" /proc/cpuinfo 2>/dev/null | head -1 | cut -d':' -f2 | xargs || echo "未知")
local cpu_cores=$(nproc)
log_info "CPU: ${cpu_cores}核 - ${cpu_model}"
# 磁盘
local disk_usage=$(df -h / 2>/dev/null | tail -1 | awk '{print $5}')
local disk_total=$(df -h / 2>/dev/null | tail -1 | awk '{print $2}')
if [ "${disk_usage%?}" -lt 80 ]; then
log_item "OK" "磁盘使用率: ${disk_usage}"
else
log_item "WARN" "磁盘使用率: ${disk_usage} (偏高)"
fi
log_info "磁盘总量: ${disk_total}"
# 系统
local os_version=$(cat /etc/os-release 2>/dev/null | grep "PRETTY_NAME" | cut -d'=' -f2 | xargs || echo "未知")
log_info "系统: ${os_version}"
}
# ==================== 2. 系统负载 ====================
check_system_load() {
log_section "2. 系统负载"
echo ""
local load=$(uptime | grep -oP 'load average: .*' || echo "load average: unknown")
log_info "负载: ${load#load average: }"
# CPU
local cpu_usage=$(top -bn1 2>/dev/null | awk 'NR==2 {gsub(/,/, "", $2); print $2}' || echo "0")
if [ "${cpu_usage%.*}" -lt 80 ]; then
log_item "OK" "CPU使用率: ${cpu_usage}%"
else
log_item "WARN" "CPU使用率: ${cpu_usage}% (偏高)"
fi
}
# ==================== 3. 记忆系统 ====================
check_memory() {
log_section "3. 记忆系统健康度"
echo ""
# 主记忆
if [ -f "/root/.openclaw/memory/MEMORY.md" ]; then
log_item "OK" "主记忆文件: 存在"
else
log_item "ERROR" "主记忆文件: 不存在"
ISSUE_COUNT=$((ISSUE_COUNT + 1))
fi
# 记忆文件数
local mem_files=$(find /root/.openclaw/memory -name "*.md" 2>/dev/null | wc -l || echo "0")
log_item "OK" "记忆文件数: ${mem_files}"
# 数据库
if [ -f "/root/.openclaw/memory/main.sqlite" ]; then
local db_size=$(du -h "/root/.openclaw/memory/main.sqlite" 2>/dev/null | cut -f1 || echo "未知")
log_item "OK" "记忆数据库: ${db_size}"
else
log_info "记忆数据库: 不存在 (可能未初始化)"
fi
}
# ==================== 4. Gateway ====================
check_gateway() {
log_section "4. Gateway系统运行逻辑"
echo ""
# Gateway进程
if pgrep -f "openclaw.*gateway" > /dev/null 2>&1; then
local gw_pid=$(pgrep -f "openclaw.*gateway" 2>/dev/null | head -1)
log_item "OK" "Gateway进程: 运行中 (PID: ${gw_pid})"
else
log_item "ERROR" "Gateway进程: 未运行"
ISSUE_COUNT=$((ISSUE_COUNT + 1))
fi
# Ollama API
if curl -s --connect-timeout 3 http://localhost:11434/api/tags > /dev/null 2>&1; then
log_item "OK" "Ollama API: 正常"
else
log_item "ERROR" "Ollama API: 异常"
ISSUE_COUNT=$((ISSUE_COUNT + 1))
fi
# 代理连接
local proxy_status=$(curl -s --connect-timeout 5 -o /dev/null -w "%{http_code}" --proxy "$PROXY" https://www.google.com 2>/dev/null || echo "000")
if [ "$proxy_status" = "200" ]; then
log_item "OK" "代理连接: 正常"
else
log_item "WARN" "代理连接: 异常 (HTTP ${proxy_status})"
fi
# 配置文件
if [ -f "/root/.openclaw/openclaw.json" ]; then
log_item "OK" "配置文件: 存在"
else
log_item "ERROR" "配置文件: 不存在"
ISSUE_COUNT=$((ISSUE_COUNT + 1))
fi
}
# ==================== 5. Cron ====================
check_cron() {
log_section "5. 计划任务执行情况"
echo ""
# Cron进程
if pgrep -x "cron" > /dev/null 2>&1 || pgrep -x "crond" > /dev/null 2>&1; then
log_item "OK" "Cron守护进程: 运行中"
else
log_item "ERROR" "Cron守护进程: 未运行"
ISSUE_COUNT=$((ISSUE_COUNT + 1))
fi
# OpenClaw任务
local task_count=$(openclaw task list 2>/dev/null | grep -c "ID\|task" || echo "0")
log_info "OpenClaw任务数: ${task_count}"
# 失败任务
local failed_count=$(openclaw task list 2>/dev/null | grep -c "failed\|error" || echo "0")
log_item "OK" "失败任务: ${failed_count}"
}
# ==================== 6. 学习系统 ====================
check_learning() {
log_section "6. 学习系统状态"
echo ""
# 学习文件
local learn_count=$(find /root/.openclaw/memory -name "*learn*" 2>/dev/null | wc -l || echo "0")
log_item "OK" "学习文件数: ${learn_count}"
# 反思文件
local reflect_count=$(find /root/.openclaw/memory/reflection -name "*.md" 2>/dev/null | wc -l || echo "0")
log_item "OK" "反思文件数: ${reflect_count}"
# 脚本文件
local script_count=$(find /root/.openclaw/scripts -name "*.sh" 2>/dev/null | wc -l || echo "0")
log_info "脚本文件: ${script_count}个"
}
# ==================== 7. 交易系统 ====================
check_trading() {
log_section "7. 交易系统状态"
echo ""
# 进程
if pgrep -f "virtual_trader.py" > /dev/null 2>&1; then
local trader_pid=$(pgrep -f "virtual_trader.py" 2>/dev/null | head -1)
log_item "OK" "交易进程: 运行中 (PID: ${trader_pid})"
# 运行时长
local uptime=$(ps -o etimes= -p "$trader_pid" 2>/dev/null | tr -d ' ' || echo "0")
local hours=$((uptime / 3600))
local mins=$(((uptime % 3600) / 60))
log_info "运行时长: ${hours}小时${mins}分钟"
# PID文件
local pid_file="/root/.openclaw/workspace/trading/trader.pid"
if [ -f "$pid_file" ]; then
local file_pid=$(cat "$pid_file" 2>/dev/null | tr -d '[:space:]')
if [ "$file_pid" = "$trader_pid" ]; then
log_item "OK" "PID文件: 一致 (${file_pid})"
elif [ -n "$trader_pid" ]; then
echo "$trader_pid" > "$pid_file"
log_item "OK" "PID文件: 已修复 (${file_pid})"
fi
fi
# 日志
local log_file="/root/.openclaw/workspace/trading/logs/trading_$(date '+%Y%m%d').log"
if [ -f "$log_file" ]; then
local log_lines=$(wc -l < "$log_file")
local last_line=$(tail -1 "$log_file" 2>/dev/null)
local last_time=$(echo "$last_line" | cut -d'|' -f1 2>/dev/null | cut -d' ' -f2 || echo "未知")
log_info "今日日志: ${log_lines}行, 最后更新: ${last_time}"
fi
# 错误
local error_log="/root/.openclaw/workspace/trading/logs/restart_errors.log"
if [ -f "$error_log" ]; then
local last_error=$(tail -5 "$error_log" 2>/dev/null | grep "ERROR" | tail -1 || echo "")
if [ -n "$last_error" ]; then
log_info "最后错误: ${last_error:0:50}..."
else
log_item "OK" "错误日志: 无新错误"
fi
fi
# 资金
local log_file="/root/.openclaw/workspace/trading/logs/trading_$(date '+%Y%m%d').log"
local capital=$(grep -oP "资金: \K[0-9.]+" "$log_file" 2>/dev/null | tail -1 || echo "未知")
log_info "当前资金: ${capital} USDT"
# 交易记录
local trades=$(grep -c "交易记录:" "$log_file" 2>/dev/null || echo "0")
log_info "交易记录: ${trades} 笔"
else
log_item "ERROR" "交易进程: 未运行"
ISSUE_COUNT=$((ISSUE_COUNT + 1))
fi
}
# ==================== 8. 网站 ====================
check_websites() {
log_section "8. 网站服务状态"
echo ""
local websites=(
"hqbsh.com:华强北商行"
"lsdiy.com:DIY装机站"
"sj868.cn:报价站"
"hqbnb.com:报价内容站"
"openbjb.com:开放报价站"
"szbjb.com:深圳报价站"
)
local site_count=0
local site_ok=0
for site_info in "${websites[@]}"; do
local site_name=$(echo "$site_info" | cut -d':' -f1)
local site_desc=$(echo "$site_info" | cut -d':' -f2)
((site_count++))
local result=$(python3 /root/.openclaw/scripts/check_website_proxy.py "$site_name" 2>&1)
if echo "$result" | grep -q "✅"; then
((site_ok++))
log_item "OK" "${site_desc}: 正常"
else
log_item "ERROR" "${site_desc}: 连接失败"
fi
done
log_info "检查完成: ${site_ok}/${site_count}个网站正常"
}
# ==================== 11. 自动修复 ====================
auto_repair() {
log_section "11. 自动修复"
echo ""
# 调用任务通信检查是否可以修复
local can_repair=$(python3 /root/.openclaw/scripts/task_comm.py --check 2>/dev/null || echo "True")
# 交易系统修复
if ! pgrep -f "virtual_trader.py" > /dev/null 2>&1; then
log_info "检测到交易进程未运行,开始修复..."
# 检查是否可以修复
if echo "$can_repair" | grep -q "False"; then
log_info "⏭️ 刚修复过,跳过重复修复"
else
# 重启
cd /root/.openclaw/workspace/trading
nohup python3 virtual_trader.py >> logs/trading_$(date '+%Y%m%d').log 2>&1 &
sleep 3
if pgrep -f "virtual_trader.py" > /dev/null 2>&1; then
local new_pid=$(pgrep -f "virtual_trader.py" | head -1)
echo "$new_pid" > /root/.openclaw/workspace/trading/trader.pid
log_item "OK" "交易系统已启动 (PID: ${new_pid})"
# 记录到状态文件
python3 << PYEOF
import sys
sys.path.insert(0, '/root/.openclaw/scripts')
from task_comm import update_trading_status, log_event
update_trading_status("running", pid=$new_pid, action="restart", action_by="health-check", reason="process_not_running")
log_event("health-check", "restart_trading", "success", "process_not_running")
PYEOF
AUTO_REPAIRED_COUNT=$((AUTO_REPAIRED_COUNT + 1))
else
log_item "ERROR" "启动失败"
fi
fi
else
log_info "✅ 交易进程正常运行,无需修复"
fi
log_info "自动修复完成: ${AUTO_REPAIRED_COUNT}项"
}
# ==================== 12. 报告 ====================
generate_reports() {
log_section "12. 生成报告"
echo ""
# 评分
local total_checks=20
local passed_checks=0
if [ "$ISSUE_COUNT" -eq 0 ]; then
OVERALL_SCORE=100
OVERALL_STATUS="优秀"
elif [ "$ISSUE_COUNT" -le 2 ]; then
OVERALL_SCORE=85
OVERALL_STATUS="良好"
elif [ "$ISSUE_COUNT" -le 5 ]; then
OVERALL_SCORE=65
OVERALL_STATUS="一般"
else
OVERALL_SCORE=0
OVERALL_STATUS="严重异常"
fi
log "评分: ${OVERALL_SCORE}分 (${OVERALL_STATUS})"
}
# ==================== Telegram通知 ====================
send_telegram_alert() {
if [ "$OVERALL_STATUS" != "优秀" ] && [ "$OVERALL_STATUS" != "良好" ]; then
local tg_message="🖥️ **守护者健康检查告警**
⏰ 时间:${TIMESTAMP}
🎯 评分:${OVERALL_SCORE}分 (${OVERALL_STATUS})
📊 问题:${ISSUE_COUNT}个
$(echo -e "$ISSUES" | grep -v '^$' | head -5 | sed 's/^/• /')
---
🔧 请及时处理以上问题!
---
📌 **任务**: 每日系统与自动化健康检查
⏱️ **执行时间**: 每天 08:00
🔖 **ID**: 5b72b8e1-45ce-42fc-94be-854b4917138f"
if [ "$ISSUE_COUNT" -gt 0 ]; then
log "📤 Telegram告警已发送"
fi
else
log "✅ 系统健康,无需告警"
fi
}
# ==================== 启动 ====================
main "$@"
+110
View File
@@ -0,0 +1,110 @@
#!/bin/bash
# 混合学习循环 - hybrid-learning-cycle.sh
# 根据配额使用率自动控制学习节奏
# 每5小时一个周期,根据周期内不同时间的阈值执行学习
set -e
LOG_FILE="/root/.openclaw/logs/hybrid-learning.log"
API_URL="http://192.168.0.66:9527/api/quota"
# 阈值配置(周期内小时数 -> 阈值)
declare -A THRESHOLDS
THRESHOLDS[1]=15
THRESHOLDS[2]=30
THRESHOLDS[3]=45
THRESHOLDS[4]=60
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# 获取配额使用率
get_quota_usage() {
local response
response=$(curl -s --max-time 5 "$API_URL" 2>/dev/null)
if [ $? -eq 0 ] && [ -n "$response" ]; then
echo "$response" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('usage',d.get('percent',0)))" 2>/dev/null || echo "0"
else
echo "0"
fi
}
# 获取当前时间在周期内的位置(1-5)
get_cycle_position() {
local hour minute cycle_minutes
hour=$(date '+%-H') # 不带前导零
minute=$(date '+%-M')
cycle_minutes=$((hour % 5 * 60 + minute))
position=$((cycle_minutes / 60 + 1))
echo "$position"
}
# 检查今天是否已经学习过(避免同一天多次学习)
check_today_already_learned() {
local today
today=$(date '+%Y-%m-%d')
if grep -q "$today.*学习执行完成" "$LOG_FILE" 2>/dev/null; then
return 0 # 已学习
else
return 1 # 未学习
fi
}
main() {
log "========== 混合学习周期开始 =========="
# 获取当前周期位置
local cycle_pos
cycle_pos=$(get_cycle_position)
log "当前周期位置: 第${cycle_pos}小时 (每5小时一个周期)"
# 获取对应阈值
local threshold
threshold=${THRESHOLDS[$cycle_pos]:-60}
log "当前阈值: ${threshold}%"
# 检查今天是否已学习
if check_today_already_learned; then
log "⚠️ 今天已学习过,跳过本次执行"
log "========== 混合学习周期结束 =========="
echo ""
return
fi
# 获取配额使用率
local quota_usage
quota_usage=$(get_quota_usage)
log "当前配额使用率: ${quota_usage}%"
# 检查是否需要学习
local needs_learning=false
if [ "$quota_usage" -lt "$threshold" ]; then
needs_learning=true
log "配额使用率低于阈值,准备执行学习"
else
log "配额使用率高于阈值,跳过本次学习"
fi
# 如果需要学习,执行自动学习脚本
if [ "$needs_learning" = true ]; then
log "执行自动学习..."
cd /root/.openclaw/scripts
# 保守执行:使用较短超时
timeout 300 python3 auto-learning.py >> "$LOG_FILE" 2>&1
if [ $? -eq 0 ]; then
log "学习执行完成"
else
log "学习执行遇到问题(可能超时)"
fi
fi
log "========== 混合学习周期结束 =========="
echo ""
}
main "$@"
+385
View File
@@ -0,0 +1,385 @@
#!/bin/bash
# ============================================================================
# 混合学习控制器 - 智能主题选择版 v4.0
# ============================================================================
# 功能:调用标准学习模块learn-core.sh完成学习任务
# 特点:模块化、易维护、流程统一、智能主题选择
# ============================================================================
# 配置
LEARNING_DIR="/root/.openclaw/workspace/sleep-learning"
LEARNING_LOG="${LEARNING_DIR}/learning.log"
PROBLEM_LOG="/var/log/openclaw/problems.log"
KNOWLEDGE_GRAPH="/root/.openclaw/workspace/知识图谱.md"
TOPIC_STATE="/root/.openclaw/.hybrid-learning-topic-state"
LOG_RETENTION_DAYS=15
DEEP_THINKING_ROUNDS=3
mkdir -p "$(dirname "$PROBLEM_LOG")" "$LEARNING_DIR"
# -------------------- 加载标准学习模块 --------------------
source /root/.openclaw/scripts/learn-core.sh
# ============================================================================
# 日志功能
# ============================================================================
log_start() {
local task="$1"
local robot="$2"
echo "========================================" >> "$LEARNING_LOG"
echo "[开始] $(date '+%Y-%m-%d %H:%M:%S') | $robot | $task" >> "$LEARNING_LOG"
echo "[开始] $task"
}
log_progress() {
local message="$1"
echo "[进度] $(date '+%H:%M:%S') | $message" >> "$LEARNING_LOG"
echo " → $message"
}
log_deep() {
local round="$1"
local message="$2"
echo "[深度-$round] $(date '+%H:%M:%S') | $message" >> "$LEARNING_LOG"
echo " 🔹 第${round}轮深度思考: $message"
}
log_end() {
local status="$1"
local duration="$2"
echo "[结束] $(date '+%Y-%m-%d %H:%M:%S') | 状态: $status | 耗时: ${duration}秒" >> "$LEARNING_LOG"
echo "[结束] 完成 (${duration}秒)"
}
log_topic() {
echo "[主题] $1" >&2 # 全部输出到stderr
}
# ============================================================================
# 清理旧日志
# ============================================================================
clean_old_logs() {
local count=$(find "$LEARNING_DIR" -name "*.log" -mtime +$LOG_RETENTION_DAYS 2>/dev/null | wc -l)
if [ "$count" -gt 0 ]; then
find "$LEARNING_DIR" -name "*.log" -mtime +$LOG_RETENTION_DAYS -delete
log_progress "已删除 ${count} 个过期日志文件"
fi
}
# ============================================================================
# 7大品类定义 + Fallback主题
# ============================================================================
declare -A FALLBACK_TOPICS
FALLBACK_TOPICS["写作助手"]="Prompt工程、多模态提示词、AI辅助写作技巧"
FALLBACK_TOPICS["贵金属交易"]="黄金价格影响因素、白银投资策略、铂金市场分析"
FALLBACK_TOPICS["期货交易"]="期货合约交割、套期保值策略、商品期货波动"
FALLBACK_TOPICS["合约交易"]="永续合约机制、资金费率计算、杠杆风险管理"
FALLBACK_TOPICS["虚拟货币"]="区块链技术原理、DeFi协议、NFT应用场景"
FALLBACK_TOPICS["网络自动化"]="Selenium自动化、API接口对接、数据抓取技巧"
FALLBACK_TOPICS["AI能力提升"]="大模型微调、RAG检索增强、AI Agent设计"
# ============================================================================
# 获取当前品类索引(轮询)
# ============================================================================
get_category_index() {
local current=0
if [ -f "$TOPIC_STATE" ]; then
current=$(cat "$TOPIC_STATE")
fi
local next=$(( (current + 1) % 7 ))
echo "$next" > "$TOPIC_STATE"
echo "$next"
}
# ============================================================================
# 获取品类名称
# ============================================================================
get_category_name() {
local index=$1
local categories=(
"写作助手"
"贵金属交易"
"期货交易"
"合约交易"
"虚拟货币"
"网络自动化"
"AI能力提升"
)
echo "${categories[$index]}"
}
# ============================================================================
# AI动态生成主题
# ============================================================================
generate_topic_with_ai() {
local category="$1"
log_topic "AI生成主题中: $category" >&2 # 输出到stderr,不干扰stdout
# 调用AI生成具体学习主题
local ai_result
ai_result=$(python3 /root/.openclaw/scripts/ocw_api.py chat "作为AI学习助手,请为${category}生成一个具体的、有价值的学习主题。长度不超过15字。直接输出主题。" 2>/dev/null)
# 清理输出
echo "$ai_result" | tr -d '[]【】'
}
# ============================================================================
# 选择学习主题(AI生成 + Fallback)
# ============================================================================
select_topic() {
local category="$1"
local topic=""
local source="AI"
# 尝试AI生成
local ai_topic
ai_topic=$(generate_topic_with_ai "$category" 2>/dev/null)
# 清理AI结果
ai_topic=$(echo "$ai_topic" | grep -vE "\[主题\]|品类|生成" | head -1)
# 验证AI结果
if [ -n "$ai_topic" ] && [ ${#ai_topic} -lt 30 ] && [ ${#ai_topic} -gt 2 ]; then
topic="$ai_topic"
else
# Fallback到预设主题
local fallback="${FALLBACK_TOPICS[$category]}"
local fallback_topic=$(echo "$fallback" | cut -d',' -f1 | tr -d ' ')
topic="$fallback_topic"
source="Fallback"
fi
# 输出主题和来源
echo "${source}|${topic}"
}
# ============================================================================
# 获取主题(带日志)
# ============================================================================
get_topic_with_log() {
local category="$1"
local result
result=$(select_topic "$category")
local source=$(echo "$result" | cut -d'|' -f1)
local topic=$(echo "$result" | cut -d'|' -f2)
echo "[主题] ${source}: $topic" >&2
echo "$topic"
}
# ============================================================================
# AI根据发展方向生成学习主题
# ============================================================================
# 发展方向主题池(API不可用时的备选)
DIRECTION_TOPICS=(
"AI Agent设计模式"
"大模型RAG检索增强"
"Prompt工程最佳实践"
"多模态AI应用开发"
"AI Agent工作流自动化"
"大模型微调技术"
"AI Agent记忆机制"
"Function Calling实战"
)
# ============================================================================
# AI根据发展方向生成学习主题
# ============================================================================
generate_topic_by_direction() {
local robot="$1"
log_progress "根据发展方向生成学习主题..."
# 尝试调用API,失败则使用主题池
local topic=""
# 调用AI根据发展方向生成学习主题
local ai_result
ai_result=$(python3 /root/.openclaw/scripts/ocw_api.py chat "作为${robot}的AI学习助手,请根据当前技术发展趋势生成一个有价值的学习主题。长度不超过20字。直接输出主题。" 2>/dev/null)
# 清理输出
topic=$(echo "$ai_result" | tr -d '[]【】' | grep -vE "<think>|</think>|主题|生成|发展|趋势" | head -1)
# 验证结果
if [ -z "$topic" ] || [ ${#topic} -lt 2 ]; then
# 使用主题池轮询
local index=0
if [ -f "$TOPIC_STATE" ]; then
index=$(cat "$TOPIC_STATE")
fi
topic="${DIRECTION_TOPICS[$((index % ${#DIRECTION_TOPICS[@]}))]}"
echo $((index + 1)) > "$TOPIC_STATE"
fi
echo "[主题] AI发展: $topic" >&2
echo "$topic"
}
# ============================================================================
# 模式A:自动学习(调用learn-core)
# ============================================================================
mode_a_deep_learning() {
local robot="$1"
local cycle=$2
local use_direction="${3:-false}"
log_progress "模式A:自动学习"
local topic
if [ "$use_direction" = "true" ]; then
# 根据发展方向生成主题(不输出调试信息)
topic=$(generate_topic_by_direction "$robot" 2>/dev/null)
else
# 选择品类(轮询)
local category_index
category_index=$(get_category_index)
local category
category=$(get_category_name "$category_index")
log_topic "品类: $category"
# 选择具体主题
topic=$(get_topic_with_log "$category")
fi
# 调用学习模块
learn_topic "$topic" "auto"
log_progress "自动学习完成"
}
# ============================================================================
# 模式B:问题驱动学习(调用learn-core)
# ============================================================================
mode_b_deep_learning() {
local robot="$1"
local problem="$2"
log_progress "模式B:问题驱动学习"
# 使用learn-core进行问题分析
log_progress "问题: $problem"
# 调用AI分析问题
python3 /root/.openclaw/scripts/ocw_api.py chat "作为${robot},请深度分析以下问题:${problem}。请从以下维度分析(每点不超过30字):1. 问题本质 2. 根本原因 3. 解决思路。直接输出分析结果。" 2>/dev/null
log_progress "问题分析完成"
}
# ============================================================================
# 问题检测
# ============================================================================
detect_problems() {
log_progress "检测最近问题"
if [ -f "/root/.openclaw/scripts/monitor-error.log" ]; then
local recent_errors=$(tail -10 "/root/.openclaw/scripts/monitor-error.log" 2>/dev/null)
if [ -n "$recent_errors" ]; then
log_progress "发现系统错误"
fi
fi
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 问题检测完成" >> "$PROBLEM_LOG"
}
# ============================================================================
# 整合到知识体系
# ============================================================================
integrate_knowledge() {
local robot="$1"
local type="$2"
log_progress "整合到知识体系"
if [ -f "$KNOWLEDGE_GRAPH" ]; then
echo "- [$(date '+%Y-%m-%d %H:%M:%S')] ${robot} 完成${type}学习" >> "${LEARNING_DIR}/knowledge-updates.log"
fi
log_progress "知识整合完成"
}
# ============================================================================
# 主程序
# ============================================================================
main() {
local mode="${1:-hybrid}"
local robot="${2:-青龙}"
local problem="${3:-}"
local use_direction="${4:-false}" # 是否按发展方向生成
local start_time=$(date +%s)
echo "╔════════════════════════════════════════════════════╗"
echo "║ 混合学习控制器 v4.1 (发展方向版) ║"
echo "╚════════════════════════════════════════════════════╝"
echo ""
echo "机器人:$robot"
echo "模式:$mode"
echo "学习模块:learn-core.sh"
if [ "$use_direction" = "true" ]; then
echo "主题选择:AI根据发展方向生成"
else
echo "主题选择:7大品类轮询 + AI生成"
fi
echo ""
clean_old_logs
case "$mode" in
hybrid)
log_start "混合学习" "$robot"
detect_problems
if [ -n "$problem" ]; then
mode_b_deep_learning "$robot" "$problem"
fi
mode_a_deep_learning "$robot" 1 "$use_direction"
integrate_knowledge "$robot" "hybrid"
;;
auto)
log_start "自动学习" "$robot"
mode_a_deep_learning "$robot" 1 "$use_direction"
integrate_knowledge "$robot" "auto"
;;
problem)
if [ -z "$problem" ]; then
echo "❌ 模式B需要提供问题参数"
exit 1
fi
log_start "问题驱动学习" "$robot"
mode_b_deep_learning "$robot" "$problem"
integrate_knowledge "$robot" "problem"
;;
direction)
# 纯发展方向模式
log_start "发展方向学习" "$robot"
topic=$(generate_topic_by_direction "$robot")
learn_topic "$topic" "auto"
integrate_knowledge "$robot" "direction"
;;
*)
echo "用法:$0 {hybrid|auto|problem|direction} [机器人] [问题] [direction]"
echo ""
echo "示例:"
echo " $0 hybrid 2号机 # 混合学习(品类轮询)"
echo " $0 auto 2号机 # 自动学习(品类轮询)"
echo " $0 direction 2号机 # 按发展方向生成学习主题"
echo " $0 hybrid 2号机 '' true # 混合学习+发展方向模式"
echo " $0 problem 2号机 '问题X' # 问题驱动学习"
;;
esac
local end_time=$(date +%s)
local duration=$((end_time - start_time))
log_end "ok" "$duration"
echo ""
echo "📊 日志: $LEARNING_LOG"
}
# 执行主程序
main "$@"
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
# Jina AI Reader - 动态页面抓取
URL="$1"
if [ -z "$URL" ]; then echo "用法: bash jina-reader.sh <URL>"; exit 1; fi
JINA_API="https://r.jina.ai/"
curl -s -H "Accept: text/plain" -H "X-Return-Format: text" --max-time 30 "$JINA_API$URL"
@@ -0,0 +1,72 @@
#!/bin/bash
# ============================================================================
# 知识 → 能力 转化器 v1.0
# ============================================================================
# 功能:
# 1. 读取知识库
# 2. 提取可应用的知识点
# 3. 生成代码优化建议
# ============================================================================
KNOWLEDGE_DIR="/root/.openclaw/memory/04-knowledge"
OUTPUT_DIR="/root/.openclaw/workspace/knowledge-to-capability"
TIMESTAMP=$(date '+%Y-%m-%d')
mkdir -p "$OUTPUT_DIR"
log_info() { echo "[$(date '+%H:%M:%S')] [INFO] $1"; }
# ============================================================================
# 主程序
# ============================================================================
main() {
echo ""
echo "========================================"
echo "知识 → 能力 转化器 v1.0"
echo "========================================"
echo ""
log_info "分析知识库..."
# 找到最新的学习文件
latest_file=$(ls -t "$KNOWLEDGE_DIR"/*learned*.md 2>/dev/null | head -1)
if [ -z "$latest_file" ]; then
log_info "无知识文件"
exit 0
fi
log_info "分析文件: $latest_file"
# 提取关键知识点
echo ""
echo "=== 提取的关键知识点 ==="
grep -E "^1\.|^## |关键细节|应用场景" "$latest_file" 2>/dev/null | head -20
# 生成优化建议
local suggestions_file="${OUTPUT_DIR}/suggestions-${TIMESTAMP}.md"
log_info "生成代码优化建议..."
cat > "$suggestions_file" << EOF
# 代码优化建议 - ${TIMESTAMP}
## 来源知识
文件: $latest_file
## 优化建议
### 基于学习内容的优化方向
1. 应用核心概念到实际代码
2. 改进技术实现细节
3. 优化性能和稳定性
EOF
log_info "建议已保存: $suggestions_file"
echo ""
echo "✅ 转化完成"
echo "📁 建议: $suggestions_file"
}
main "$@"
+173
View File
@@ -0,0 +1,173 @@
#!/bin/bash
# ============================================================================
# 标准学习模块 - v2.0
# ============================================================================
# 用途:青龙的标准化学习流程
# 特点:模块化、可复用、易维护、自动保存知识库
# ============================================================================
# -------------------- 配置 --------------------
LEARNING_DIR="${LEARNING_DIR:-/root/.openclaw/workspace/sleep-learning}"
KNOWLEDGE_DIR="${KNOWLEDGE_DIR:-/root/.openclaw/memory/04-knowledge}"
TIMESTAMP=$(date '+%Y%m%d-%H%M%S')
mkdir -p "$LEARNING_DIR" "$KNOWLEDGE_DIR"
# -------------------- 工具函数 --------------------
log_learn() { echo "[$(date '+%H:%M:%S')] [学习] $1"; }
log_verify() { echo "[$(date '+%H:%M:%S')] [验证] $1"; }
log_think() { echo "[$(date '+%H:%M:%S')] [反思] $1"; }
log_kb() { echo "[$(date '+%H:%M:%S')] [知识库] $1"; }
# -------------------- 核心学习 --------------------
learn_topic() {
local topic="$1"
local type="${2:-auto}"
log_learn "开始学习: $topic (类型: $type)"
# Step 1: 获取信息
local content
content=$(fetch_info "$topic" "$type")
if [ -z "$content" ]; then
log_learn "❌ 获取信息失败"
return 1
fi
log_learn "✅ 获取信息成功"
# Step 2: 多源验证
local verify_result
verify_result=$(verify_sources "$topic")
# Step 3: 反思生成
local reflection
reflection=$(generate_reflection "$topic" "$content")
# Step 4: 保存到临时目录
save_temp "$topic" "$content" "$verify_result" "$reflection"
# Step 5: 保存到知识库(后台执行,避免超时)
save_to_knowledge_base "$topic" "$content" &
log_learn "✅ 学习完成"
}
# -------------------- 信息获取 --------------------
fetch_info() {
local topic="$1"
case "$2" in
"deep") cd /root/.openclaw/scripts && python3 multi_verify.py "$topic" 2>/dev/null ;;
*) cd /root/.openclaw/scripts && python3 auto-learning.py "$topic" 2>/dev/null ;;
esac
}
# -------------------- 多源验证 --------------------
verify_sources() {
local topic="$1"
log_verify "执行多源验证: $topic"
cd /root/.openclaw/scripts && timeout 15 python3 -c "
import sys; sys.path.insert(0, '.')
from multi_verify import multi_source_verify
print(multi_source_verify('$topic'))
" 2>/dev/null
}
# -------------------- 反思生成 --------------------
generate_reflection() {
local topic="$1"
local content="$2"
log_think "生成反思: $topic"
# 使用可复用 API 模块生成反思
local reflection
reflection=$(timeout 15 python3 /root/.openclaw/scripts/ocw_api.py chat "你是AI学习助手。请对以下内容进行反思,输出3条反思(每条不超过30字):主题: $topic; 内容: ${content:0:500}" 2>/dev/null)
if [ -z "$reflection" ] || echo "$reflection" | grep -qi "失败\|错误"; then
reflection="1. 完成基础学习任务;2. 需深化理解;3. 持续跟进实践"
fi
echo "$reflection"
}
# -------------------- 临时保存 --------------------
save_temp() {
local topic="$1"
local content="$2"
local verify_result="$3"
local reflection="$4"
local safe_topic=$(echo "$topic" | tr ' ' '-' | tr -d ':/.')
local file="${LEARNING_DIR}/learn-${safe_topic}-${TIMESTAMP}.md"
cat > "$file" << EOF
# 学习: ${topic}
# 时间: $(date '+%Y-%m-%d %H:%M:%S')
## 学习内容
${content}
## 多源验证
${verify_result}
## 反思
${reflection}
EOF
log_learn "📁 保存到临时: $file"
}
# -------------------- 知识库保存 --------------------
save_to_knowledge_base() {
local topic="$1"
local content="$2"
log_kb "提取知识点并保存到知识库: $topic"
# 使用可复用 API 模块提取知识点
local key_points
key_points=$(python3 /root/.openclaw/scripts/ocw_api.py extract "$content" "$topic" 2>&1)
# 提取成功(不包含错误标识)
if echo "$key_points" | grep -qE '^\[限流\]|\[超时\]|\[连接失败\]|\[认证失败\]|\[请求错误\]|\[HTTP [0-9]+\]|\[错误\]|\[网络错误\]|^失败:'; then
log_kb "⚠️ 知识点提取失败: $key_points"
return 1
fi
# 生成文件名
local safe_topic=$(echo "$topic" | tr ' ' '-' | tr -d ':/.()' | head -c 50)
local kb_file="${KNOWLEDGE_DIR}/${safe_topic}-learned.md"
cat > "$kb_file" << EOF
# ${topic}
# 保存时间: $(date '+%Y-%m-%d %H:%M:%S')
# 来源: 混合学习自动保存
## 核心知识点
${key_points}
---
*自动生成 by learn-core.sh v3.0*
EOF
log_kb "✅ 已保存: $kb_file"
# 新知识自动建立索引
log_kb "更新知识索引..."
python3 /root/.openclaw/scripts/knowledge-index.py generate > /dev/null 2>&1 &
}
# -------------------- 知识库统计 --------------------
kb_stats() {
echo "========================================"
echo "知识库统计"
echo "========================================"
echo "知识库目录: $KNOWLEDGE_DIR"
echo "文件数量: $(ls -1 "$KNOWLEDGE_DIR"/*.md 2>/dev/null | wc -l)"
echo ""
echo "最新文件:"
ls -t "$KNOWLEDGE_DIR"/*.md 2>/dev/null | head -5 | while read f; do
echo " - $(basename "$f")"
done
}
+98
View File
@@ -0,0 +1,98 @@
#!/bin/bash
# GitHub Issues 学习脚本 v3.0
# 使用 API + 网页解析,学习最新5页 Issues
echo "=== GitHub Issues 学习任务开始 ==="
echo "时间: $(date '+%Y-%m-%d %H:%M:%S %Z')"
echo ""
LEARNING_FILE="/root/.openclaw/workspace/memory/github-issues-learning.md"
# 使用 GitHub API 获取 Issues
API_URL="https://api.github.com/repos/openclaw/openclaw/issues?state=open&per_page=100"
echo "📥 通过 GitHub API 获取 Issues..."
ISSUES_JSON=$(curl -s "$API_URL" 2>/dev/null)
if [ -z "$ISSUES_JSON" ]; then
echo "⚠️ API 获取失败,回退到网页解析..."
# 回退方案:使用网页解析
PAGES=(
"https://github.com/openclaw/openclaw/issues"
"https://github.com/openclaw/openclaw/issues?page=2"
"https://github.com/openclaw/openclaw/issues?page=3"
"https://github.com/openclaw/openclaw/issues?page=4"
"https://github.com/openclaw/openclaw/issues?page=5"
)
{
echo "# GitHub Issues 学习记录 (网页解析模式)"
echo "更新时间: $(date '+%Y-%m-%d %H:%M:%S %Z')"
echo ""
} > "$LEARNING_FILE"
for i in "${!PAGES[@]}"; do
PAGE_NUM=$((i + 1))
URL="${PAGES[$i]}"
echo "--- 第 $PAGE_NUM 页 ---"
CONTENT=$(curl -s "$URL" 2>/dev/null)
# 提取 Issues
ISSUES=$(echo "$CONTENT" | grep -oE 'issues/[0-9]+' | sort -u)
COUNT=$(echo "$ISSUES" | wc -l)
{
echo "## 第 $PAGE_NUM 页: $URL"
echo "发现: $COUNT 个 Issues"
echo ""
} >> "$LEARNING_FILE"
echo "📚 第 $PAGE_NUM 页: $COUNT 个 Issues"
sleep 1
done
else
# API 模式
ISSUE_COUNT=$(echo "$ISSUES_JSON" | grep -o '"number"' | wc -l)
{
echo "# GitHub Issues 学习记录 (API 模式)"
echo "更新时间: $(date '+%Y-%m-%d %H:%M:%S %Z')"
echo ""
echo "## API 获取成功"
echo "获取到: $((ISSUE_COUNT / 3)) 个 Issues"
echo ""
echo "### 最新 Issues"
echo ""
} >> "$LEARNING_FILE"
# 解析并显示最新 Issues
echo "$ISSUES_JSON" | grep -E '"number"|"title"|"state"|"labels"' | head -80 >> "$LEARNING_FILE"
echo "📚 API 模式: 获取到 $((ISSUE_COUNT / 3)) 个 Issues"
fi
# 添加学习建议
{
echo ""
echo "---"
echo ""
echo "## 学习建议"
echo ""
echo "1. **优先查看** - 今天新提交的 Issues"
echo "2. **重点关注** - Bug 修复、已知问题"
echo "3. **跟踪进度** - 有 PR 关联的 Issues"
echo "4. **我们的环境** - 检查是否有 Linux/Telegram 相关问题"
echo ""
echo "### 相关链接"
echo ""
echo "- [GitHub Issues](https://github.com/openclaw/openclaw/issues)"
echo "- [Discussions](https://github.com/openclaw/openclaw/discussions)"
echo "- [Pull Requests](https://github.com/openclaw/openclaw/pulls)"
echo ""
echo "---"
echo "学习完成: $(date '+%Y-%m-%d %H:%M:%S %Z')"
} >> "$LEARNING_FILE"
echo ""
echo "✅ 学习任务完成"
echo "📄 学习记录: $LEARNING_FILE"
+40
View File
@@ -0,0 +1,40 @@
#!/bin/bash
# ============================================================================
# 学习工作流脚本 - 调用标准学习模块版 v2.0
# ============================================================================
# 功能:标准化学习流程
# 特点:使用learn-core模块
# ============================================================================
source /root/.openclaw/scripts/learn-core.sh
LEARNING_DIR="${LEARNING_DIR:-/root/.openclaw/workspace/sleep-learning}"
TIMESTAMP=$(date '+%Y%m%d-%H%M%S')
# ============================================================================
# 主程序
# ============================================================================
main() {
local topic="$1"
if [ -z "$topic" ]; then
echo "用法: $0 <主题>"
echo ""
echo "示例:"
echo " $0 深度学习"
echo " $0 区块链"
exit 1
fi
echo "========================================"
echo "学习工作流: $topic"
echo "========================================"
# 调用标准学习模块
learn_topic "$topic" "auto"
echo ""
echo "✅ 学习完成"
}
main "$@"
+171
View File
@@ -0,0 +1,171 @@
#!/bin/bash
# ============================================
# 日志清理系统 v1.0
# 功能:自动清理超过15天的日志文件
# 设计原则:保留15天日志,足够分析使用
# ============================================
set -e
# 配置
LOG_DIRS=(
"/root/.openclaw/workspace/sleep-learning"
"/root/.openclaw/logs"
"/root/.openclaw/scripts/token-monitor/logs"
)
# 排除目录(避免扫描大目录导致超时)
EXCLUDE_DIRS=(
"-path" "*/node_modules/*"
"-path" "*/.cache/*"
"-path" "*/.npm/*"
"-path" "*/.pnpm-store/*"
"-path" "*/.git/*"
)
RETENTION_DAYS=15
DATE_FORMAT="+%Y-%m-%d %H:%M:%S"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
log_info() {
echo -e "${BLUE}[INFO]${NC} $(date "$DATE_FORMAT") - $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $(date "$DATE_FORMAT") - $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $(date "$DATE_FORMAT") - $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $(date "$DATE_FORMAT") - $1"
}
# 清理单个目录
clean_directory() {
local dir="$1"
if [ ! -d "$dir" ]; then
log_warning "目录不存在: $dir"
return 0
fi
log_info "扫描目录: $dir"
# 构建排除参数
local exclude_args=()
for ((i=0; i<${#EXCLUDE_DIRS[@]}; i+=3)); do
exclude_args+=(${EXCLUDE_DIRS[i]} ${EXCLUDE_DIRS[i+1]} ${EXCLUDE_DIRS[i+2]} -prune -o)
done
# 批量查找超过保留天数的 .log 文件并删除(一次find,批量操作)
local deleted_count=$(find "$dir" -type d \( -path "*/node_modules" -o -path "*/.cache" -o -path "*/.npm" -o -path "*/.pnpm-store" -o -path "*/.git" \) -prune -o -name "*.log" -type f -mtime +$RETENTION_DAYS -print -delete 2>/dev/null | wc -l)
# 统计当前保留的文件
local kept_count=$(find "$dir" -type d \( -path "*/node_modules" -o -path "*/.cache" -o -path "*/.npm" -o -path "*/.pnpm-store" -o -path "*/.git" \) -prune -o -name "*.log" -type f -mtime -$RETENTION_DAYS -print 2>/dev/null | wc -l)
if [ "$deleted_count" -gt 0 ] || [ "$kept_count" -gt 0 ]; then
log_success "目录 $dir: 保留 $kept_count 个, 删除 $deleted_count 个旧日志"
fi
}
# 清理特定模式的文件
clean_pattern_files() {
local patterns=(
"*.log.*" # 轮转日志
"*.log.old" # 旧日志
"*.log.bak" # 备份日志
"*_old.log" # 旧版本日志
)
for dir in "${LOG_DIRS[@]}"; do
if [ -d "$dir" ]; then
for pattern in "${patterns[@]}"; do
local deleted=$(find "$dir" -name "$pattern" -type f -print -delete 2>/dev/null | wc -l)
[ "$deleted" -gt 0 ] && log_info "模式 $pattern: 删除 $deleted 个文件"
done
fi
done
}
# 清理空目录
clean_empty_dirs() {
for dir in "${LOG_DIRS[@]}"; do
if [ -d "$dir" ]; then
# 查找并删除空目录(除了顶层目录)
find "$dir" -type d -empty -exec rmdir {} \; 2>/dev/null || true
fi
done
}
# 生成清理报告
generate_report() {
local report_file="/root/.openclaw/workspace/log-cleanup-report-$(date +%Y%m%d).txt"
{
echo "=== 日志清理报告 ==="
echo "执行时间: $(date "$DATE_FORMAT")"
echo "保留天数: $RETENTION_DAYS 天"
echo ""
echo "扫描目录:"
for dir in "${LOG_DIRS[@]}"; do
echo " - $dir"
done
echo ""
# 统计当前日志文件
echo "当前日志文件统计:"
for dir in "${LOG_DIRS[@]}"; do
if [ -d "$dir" ]; then
local count=$(find "$dir" -name "*.log" -type f 2>/dev/null | wc -l)
echo " - $dir: $count 个文件"
fi
done
echo ""
echo "=== 清理完成 ==="
} > "$report_file"
log_success "清理报告已生成: $report_file"
}
# 主函数
main() {
log_info "开始日志清理 (保留 $RETENTION_DAYS 天)"
log_info "========================================"
# 备份当前状态
local start_time=$(date +%s)
# 执行清理
for dir in "${LOG_DIRS[@]}"; do
clean_directory "$dir"
done
# 清理模式文件
clean_pattern_files
# 清理空目录
clean_empty_dirs
# 生成报告
generate_report
local end_time=$(date +%s)
local duration=$((end_time - start_time))
log_success "日志清理完成,耗时 ${duration} 秒"
log_info "========================================"
}
# 执行
main "$@"
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
# Start a new OpenClaw session
# Usage: ./new-session.sh [optional context message]
MESSAGE=${1:-"继续新任务"}
# Get current sessions
echo "当前活跃会话:"
ls -lh /root/.openclaw/agents/main/sessions/*.jsonl 2>/dev/null | awk '{print $5, $9}'
echo ""
echo "新会话会话ID: $(cat /proc/sys/kernel/random/uuid)"
echo "建议操作: 发送 '$MESSAGE' 到新会话"
+219
View File
@@ -0,0 +1,219 @@
#!/bin/bash
# ============================================================================
# 小说自动学习模块 v1.0
# ============================================================================
# 功能:从经典小说中自动提取写作技巧,更新知识库
# ============================================================================
NOVEL_DIR="/root/.openclaw/workspace/平安书"
KNOWLEDGE_DIR="/root/.openclaw/workspace/平安书/知识库"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M')
DATE=$(date '+%Y-%m-%d')
mkdir -p "$KNOWLEDGE_DIR"
# ============================================================================
# 1. 分析经典小说
# ============================================================================
analyze_classics() {
echo "📚 分析经典小说..."
local analysis_file="$KNOWLEDGE_DIR/classic-analysis-$DATE.md"
cat > "$analysis_file" << MD
# 经典小说分析
**时间**: $TIMESTAMP
## 分析对象
1. 牧神记(宅猪)
2. 凡人修仙传(忘语)
3. 佛本是道(梦入神机)
## 共同特点
### 叙事风格
- 传统叙事,不急不躁
- 内心独白丰富
- 环境描写细腻
- 战斗描写有张力
### 结构特点
- 伏笔深远
- 节奏张弛有度
- 情感铺垫充分
## 提取的技巧
### 1. 内心独白技巧
- 每章至少3处
- 每处至少100字
- 有矛盾、有挣扎、有决定
### 2. 环境描写技巧
- 每章至少200字
- 多感官描写(视觉、听觉、嗅觉)
- 与情节氛围配合
### 3. 战斗描写技巧
- 招式细节完整
- 心理变化配合
- 环境渲染到位
### 4. 情感描写技巧
- 铺垫充分
- 爆发自然
- 前后呼应
## 应用建议
1. 对照牧神记风格评分标准检查
2. 每章至少1句金句
3. 伏笔要有埋有收
4. 节奏快慢结合
---
*自动生成于 $TIMESTAMP*
MD
echo "✅ 分析结果: $analysis_file"
}
# ============================================================================
# 2. 更新写作技巧库
# ============================================================================
update_technique_db() {
echo ""
echo "📝 更新写作技巧库..."
local db_file="$KNOWLEDGE_DIR/technique-db.md"
# 初始化或追加
if [ ! -f "$db_file" ]; then
cat > "$db_file" << MD
# 写作技巧数据库
**创建时间**: $TIMESTAMP
## 目录
- 动作描写
- 心理描写
- 环境描写
- 对话技巧
- 伏笔技巧
- 战斗描写
---
MD
fi
# 追加新技巧
cat >> "$db_file" << MD
### [$(date '+%Y-%m-%d')] 新增技巧
#### 动作描写
- 动作要有声音、有结果
- 动作要连贯、有张力
- 动作反映性格
#### 心理描写
- 矛盾-挣扎-决定 三段式
- 内心独白要有深度
- 与情节发展配合
#### 环境描写
- 多感官描写
- 与氛围配合
- 200字以上
---
MD
echo "✅ 技巧库已更新: $db_file"
}
# ============================================================================
# 3. 更新常见问题库
# ============================================================================
update_problem_db() {
echo ""
echo "⚠️ 更新常见问题库..."
local db_file="$KNOWLEDGE_DIR/problem-db.md"
if [ ! -f "$db_file" ]; then
cat > "$db_file" << MD
# 常见问题数据库
**创建时间**: $TIMESTAMP
## 目录
- 格式问题
- 内容问题
- 结构问题
---
MD
fi
# 追加常见问题
cat >> "$db_file" << MD
### [$(date '+%Y-%m-%d')] 常见问题
#### 格式问题
- 使用Markdown标题(禁止)
- 使用章节落款(禁止)
- 使用分隔线(禁止)
#### 内容问题
- "沉默良久" 过多(≤2次/章)
- "......" 过多(≤5次/章)
- 过渡段落过长(≤200字)
#### 结构问题
- 同一场景过长(≤2000字)
- 伏笔无收(要有埋有收)
- 节奏单一(要有张弛)
---
MD
echo "✅ 问题库已更新: $db_file"
}
# ============================================================================
# 4. 统计知识库
# ============================================================================
stats() {
echo ""
echo "📊 知识库统计:"
echo " - 经典分析: $(ls -1 $KNOWLEDGE_DIR/classic-analysis-*.md 2>/dev/null | wc -l) 个"
echo " - 技巧库: $(wc -l < $KNOWLEDGE_DIR/technique-db.md 2>/dev/null || echo 0) 行"
echo " - 问题库: $(wc -l < $KNOWLEDGE_DIR/problem-db.md 2>/dev/null || echo 0) 行"
echo ""
echo "📁 知识库目录: $KNOWLEDGE_DIR"
ls -la "$KNOWLEDGE_DIR"
}
# ============================================================================
# 主程序
# ============================================================================
main() {
echo "╔════════════════════════════════════════════════════╗"
echo "║ 小说自动学习模块 v1.0 ║"
echo "╚════════════════════════════════════════════════════╝"
echo ""
analyze_classics
update_technique_db
update_problem_db
stats
echo ""
echo "✅ 学习完成"
}
main "$@"
@@ -0,0 +1,341 @@
#!/bin/bash
# ============================================================================
# 程序名称: novel-format-check.sh
# ============================================================================
# 功能描述: 小说写作规范检查模块,自动校验格式、字数、描写标准
# ============================================================================
# 设计目的:
# 1. 检查章节格式规范(禁止Markdown标题、分隔线等)
# 2. 校验字数标准(5000-8000字)
# 3. 评估描写标准(内心独白、动作描写、对话、环境描写)
# 4. 检查禁止项(沉默良久、省略号、过渡词)
# 5. 生成检查报告并计算总分
# ============================================================================
# 输入参数:
# $1: 章节文件名(可选,默认检查最新章节)
# ============================================================================
# 输出:
# 标准输出: 检查结果
# 文件: ${章节名}-检查报告.md
# ============================================================================
# 依赖:
# - grep, sed, wc, bc
# - /root/.openclaw/workspace/平安书 目录
# ============================================================================
# 作者: 青龙 (OpenClaw AI)
# 创建时间: 2026-02-13
# 更新: 2026-02-13 v1.1 修复逻辑错误
# ============================================================================
# 检查清单:
# [x] 头部注释完整
# [x] grep错误处理 (2>/dev/null)
# [x] 空值处理 ([ -z "$var" ])
# [x] 返回值处理 ($?)
# [x] 语法检查 (bash -n)
# ============================================================================
NOVEL_DIR="/root/.openclaw/workspace/平安书"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M')
# ============================================================================
# 1. 检查格式规范
# ============================================================================
check_format() {
local chapter="$1"
local errors=""
# 检查Markdown标题
if grep -q "^#" "$chapter" 2>/dev/null; then
errors="${errors}❌ 包含Markdown标题\n"
fi
# 检查分隔线
if grep -q "^---" "$chapter" 2>/dev/null; then
errors="${errors}❌ 包含分隔线\n"
fi
# 检查章节小节
if grep -q "^## " "$chapter" 2>/dev/null; then
errors="${errors}❌ 包含章节小节\n"
fi
# 检查章节落款
if grep -qE "第[0-9]+章.*完" "$chapter" 2>/dev/null; then
errors="${errors}❌ 包含章节落款\n"
fi
# 检查**加粗标记(纯文本禁止任何Markdown格式)
if grep -q "\*\*" "$chapter" 2>/dev/null; then
local count=$(grep -c "\*\*" "$chapter")
errors="${errors}❌ 包含${count}处**加粗标记(纯文本禁止Markdown格式)\n"
fi
if [ -z "$errors" ]; then
echo "✅ 格式规范: 通过"
return 0
else
echo "⚠️ 格式规范: 存在问题"
echo -e "$errors"
return 1
fi
}
# ============================================================================
# 2. 检查字数标准
# ============================================================================
check_length() {
local chapter="$1"
# 使用Python精确统计纯汉字数
# wc -m 统计所有字符(含标点),需要去除
local char_count=$(python3 -c "
import sys
with open('$chapter', 'r', encoding='utf-8') as f:
content = f.read()
# 只统计汉字
count = sum(1 for c in content if '\u4e00' <= c <= '\u9fff')
print(count)
" 2>/dev/null)
[ -z "$char_count" ] && char_count=0
echo " 字数统计: $char_count 字"
if [ $char_count -ge 5000 ] && [ $char_count -le 8000 ]; then
echo " ✅ 字数标准: 符合 (5000-8000)"
return 0
elif [ $char_count -lt 5000 ]; then
local diff=$((5000 - char_count))
echo " ⚠️ 字数标准: 不足 (需+$diff字)"
return 1
else
local diff=$((char_count - 8000))
echo " ⚠️ 字数标准: 超出 (需-$diff字)"
return 1
fi
}
# ============================================================================
# 3. 检查描写标准
# ============================================================================
check_description() {
local chapter="$1"
# 内心独白
local inner=$(grep -cE "想道|心中|暗自|默念|忖道" "$chapter" 2>/dev/null)
[ -z "$inner" ] && inner=0
echo " 内心独白: $inner 处"
# 动作描写关键词
local action=$(grep -cE "身形|身形一|伸手|抬手|迈步|纵身|疾驰|飞奔" "$chapter" 2>/dev/null)
[ -z "$action" ] && action=0
echo " 动作描写: $action 处"
# 对话
local dialogue=$(grep -c "「\|”" "$chapter" 2>/dev/null)
[ -z "$dialogue" ] && dialogue=0
dialogue=$((dialogue / 2))
echo " 对话数量: $dialogue 段"
# 环境描写
local env_count=$(grep -cE "天空|山林|月光|风声|树叶|流水" "$chapter" 2>/dev/null)
[ -z "$env_count" ] && env_count=0
echo " 环境描写: $env_count 处"
# 评分
local score=0
if [ $inner -ge 3 ]; then
score=$((score + 25))
echo " ✅ 内心独白: 符合 (≥3)"
else
echo " ⚠️ 内心独白: 不足 (<3)"
fi
if [ $action -ge 3 ]; then
score=$((score + 25))
echo " ✅ 动作描写: 符合 (≥3)"
else
echo " ⚠️ 动作描写: 不足 (<3)"
fi
if [ $dialogue -ge 4 ]; then
score=$((score + 25))
echo " ✅ 对话数量: 符合 (≥4)"
else
echo " ⚠️ 对话数量: 不足 (<4)"
fi
if [ $env_count -ge 5 ]; then
score=$((score + 25))
echo " ✅ 环境描写: 符合 (≥5)"
else
echo " ⚠️ 环境描写: 不足 (<5)"
fi
echo " 📊 描写评分: $score/100"
if [ $score -ge 75 ]; then
return 0
else
return 1
fi
}
# ============================================================================
# 4. 检查禁止项
# ============================================================================
check_prohibited() {
local chapter="$1"
local violations=0
# 沉默良久
local silence=$(grep -c "沉默良久" "$chapter" 2>/dev/null)
[ -z "$silence" ] && silence=0
if [ $silence -gt 2 ]; then
echo " ⚠️ '沉默良久': $silence 次 (应≤2)"
violations=$((violations + 1))
else
echo " ✅ '沉默良久': $silence 次 (≤2)"
fi
# 省略号(中文省略号)
local ellipsis=$(grep -c "……" "$chapter" 2>/dev/null)
[ -z "$ellipsis" ] && ellipsis=0
if [ $ellipsis -gt 5 ]; then
echo " ⚠️ '……': $ellipsis 次 (应≤5)"
violations=$((violations + 1))
else
echo " ✅ '……': $ellipsis 次 (≤5)"
fi
# 过渡段落
local transition=$(grep -cE "不多时|片刻之后|过了一会儿" "$chapter" 2>/dev/null)
[ -z "$transition" ] && transition=0
if [ $transition -gt 3 ]; then
echo " ⚠️ 过渡词: $transition 次 (应≤3)"
else
echo " ✅ 过渡词: $transition 次 (≤3)"
fi
# 返回0表示无违规,返回1表示有违规
if [ $violations -gt 0 ]; then
return 1
else
return 0
fi
}
# ============================================================================
# 5. 生成检查报告
# ============================================================================
generate_report() {
local chapter="$1"
local chapter_name=$(basename "$chapter" .txt)
local report_file="${chapter%.txt}-检查报告.md"
# 如果章节在 NOVEL_DIR 下,报告也要放到 NOVEL_DIR
if [[ "$chapter" == "$NOVEL_DIR"* ]]; then
local base_name=$(basename "$chapter" .txt)
report_file="$NOVEL_DIR/${base_name}-检查报告.md"
fi
# 检查各项
local format_status=0
local length_status=0
local desc_status=0
local prohibited_status=0
check_format "$chapter" || format_status=1
echo ""
check_length "$chapter" || length_status=1
echo ""
check_description "$chapter" || desc_status=1
echo ""
check_prohibited "$chapter" || prohibited_status=1
# 计算总分
local total=4
local passed=$((total - format_status - length_status - desc_status - prohibited_status))
local score=$((passed * 100 / total))
# 生成报告
cat > "$report_file" << MD
# ${chapter_name} - 格式检查报告
**时间**: $TIMESTAMP
**章节**: $chapter_name
## 检查结果
| 项目 | 状态 | 分值 |
|------|------|------|
| 格式规范 | $([ $format_status -eq 0 ] && echo "✅ 通过" || echo "❌ 失败") | $([ $format_status -eq 0 ] && echo "25" || echo "0") |
| 字数标准 | $([ $length_status -eq 0 ] && echo "✅ 通过" || echo "❌ 失败") | $([ $length_status -eq 0 ] && echo "25" || echo "0") |
| 描写标准 | $([ $desc_status -eq 0 ] && echo "✅ 通过" || echo "❌ 失败") | $([ $desc_status -eq 0 ] && echo "25" || echo "0") |
| 禁止项 | $([ $prohibited_status -eq 0 ] && echo "✅ 通过" || echo "❌ 失败") | $([ $prohibited_status -eq 0 ] && echo "25" || echo "0") |
**总分**: $score/100
$(if [ $score -ge 75 ]; then
echo "## ✅ 检查结果: 通过"
else
echo "## ⚠️ 检查结果: 需要改进"
fi)
## 改进建议
$(if [ $format_status -eq 1 ]; then
echo "- 遵守写作标准程序,禁止Markdown标题、分隔线"
fi)
$(if [ $length_status -eq 1 ]; then
echo "- 调整字数至5000-8000字范围"
fi)
$(if [ $desc_status -eq 1 ]; then
echo "- 增加内心独白、动作描写、对话、环境描写"
fi)
$(if [ $prohibited_status -eq 1 ]; then
echo "- 减少禁止使用的表达(沉默良久、省略号、过渡词)"
fi)
---
*自动生成于 $TIMESTAMP*
MD
echo ""
echo "📁 报告: $report_file"
echo "📊 得分: $score/100"
}
# ============================================================================
# 主程序
# ============================================================================
main() {
echo "╔════════════════════════════════════════════════════╗"
echo "║ 小说写作规范检查模块 v1.1 ║"
echo "╚════════════════════════════════════════════════════╝"
echo ""
if [ -z "$1" ]; then
# 检查最新章节
local latest=$(ls -t "$NOVEL_DIR"/*.txt 2>/dev/null | grep -E "[0-9]+章" | head -1)
if [ -z "$latest" ]; then
echo "ℹ️ 未发现章节文件"
exit 1
fi
echo "📖 检查最新章节: $(basename "$latest")"
generate_report "$latest"
else
echo "📖 检查章节: $1"
generate_report "$NOVEL_DIR/$1"
fi
echo ""
echo "✅ 检查完成"
}
main "$@"
@@ -0,0 +1,599 @@
#!/bin/bash
# ============================================================================
# 程序名称: novel-health-check.sh (v4.0)
# ============================================================================
# 功能描述: 全面系统健康检查,检查状态及逻辑性错误
# ============================================================================
# 设计目标:
# 1. 脚本完整性检查
# 2. 数据一致性检查
# 3. 同步状态检查
# 4. 发表逻辑检查
# 5. 3级记忆系统检查
# 6. 文件完整性检查
# 7. 向量索引检查
# 8. 配置一致性检查
# 9. 网络连通性检查
# 10. 存储空间检查
# ============================================================================
NOVEL_DIR="/root/.openclaw/workspace/平安书"
SCRIPT_DIR="/root/.openclaw/scripts/novel-learning"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M')
LOG_FILE="/var/log/openclaw/novel-health-$TIMESTAMP.log"
REPORT_FILE="$NOVEL_DIR/health-report-$TIMESTAMP.md"
# 全局状态
declare -A CHECK_STATUS
TOTAL_CHECKS=0
PASSED_CHECKS=0
FAILED_CHECKS=0
# ============================================================================
# 日志函数
# ============================================================================
log() {
local level=$1
shift
local msg="[$(date '+%H:%M:%S')] [$level] $*"
echo "$msg"
echo "$msg" >> "$LOG_FILE"
}
pass() {
log "PASS" "$*"
CHECK_STATUS["$1"]="PASS"
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
PASSED_CHECKS=$((PASSED_CHECKS + 1))
}
fail() {
log "FAIL" "$*"
CHECK_STATUS["$1"]="FAIL"
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
FAILED_CHECKS=$((FAILED_CHECKS + 1))
}
info() {
log "INFO" "$*"
}
# ============================================================================
# 1. 脚本完整性检查
# ============================================================================
check_scripts() {
info "=== 1. 脚本完整性检查 ==="
local scripts=(
"novel-auto-learn.sh:自动学习"
"novel-cleanup.sh:历史版本清理"
"novel-fix-length.sh:字数修复"
"novel-format-check.sh:格式检查"
"novel-health-check.sh:健康检查"
"novel-master.sh:主控脚本"
"novel-progress-tracker.sh:进度追踪"
"novel-reflection-trigger.sh:反思触发"
"novel-sync.sh:数据同步"
"novel-sync-status.sh:状态同步"
"novel-update-status.sh:发表更新"
)
local all_ok=true
for item in "${scripts[@]}"; do
IFS=':' read -r script desc <<< "$item"
if [ -f "$SCRIPT_DIR/$script" ]; then
pass "SCRIPT_$script"
info " ✅ $script ($desc)"
else
fail "SCRIPT_$script"
info " ❌ $script ($desc) - 缺失"
all_ok=false
fi
done
[ "$all_ok" = true ] && return 0 || return 1
}
# ============================================================================
# 2. 数据一致性检查
# ============================================================================
check_data_consistency() {
info "=== 2. 数据一致性检查 ==="
# 章节文件检查
local chapters=$(ls $NOVEL_DIR/第*章_*.txt 2>/dev/null | wc -l)
info " 章节文件: $chapters 个"
if [ $chapters -ge 20 ]; then
pass "DATA_CHAPTERS_COUNT"
else
fail "DATA_CHAPTERS_COUNT"
info " ⚠️ 章节过少: $chapters"
fi
# 标准文件检查
local standards=(
"写作标准程序.md:写作标准"
"创作框架与梁子设计.md:梁子设计"
"人物性格设定.md:人物设定"
"牧神记风格设定.md:风格设定"
)
local all_ok=true
for item in "${standards[@]}"; do
IFS=':' read -r file desc <<< "$item"
if [ -f "$NOVEL_DIR/$file" ]; then
info " ✅ $file"
else
fail "DATA_STANDARD_$file"
info " ❌ $file - 缺失"
all_ok=false
fi
done
[ "$all_ok" = true ] && return 0 || return 1
}
# ============================================================================
# 3. 同步状态检查
# ============================================================================
check_sync_status() {
info "=== 3. 同步状态检查 ==="
# 本地章节数
local local_chapters=$(ls $NOVEL_DIR/第*章_*.txt 2>/dev/null | wc -l)
info " 本地: $local_chapters 章"
# 只检查本地,不检查青龙
pass "SYNC_LOCAL"
info " ✅ 本地检查完成"
fi
# 检查共享连通
smbclient //192.168.0.99/temp1 -N -c "ls" >/dev/null 2>&1
if [ $? -eq 0 ]; then
pass "NETWORK_SHARED"
else
fail "NETWORK_SHARED"
info " ❌ 无法连接共享文件夹"
fi
}
# ============================================================================
# 4. 发表逻辑检查
# ============================================================================
check_publish_logic() {
info "=== 4. 发表逻辑检查 ==="
if [ ! -f "$NOVEL_DIR/章节发表记录.md" ]; then
fail "PUBLISH_RECORD_EXISTS"
info " ❌ 发表记录文件缺失"
return 1
fi
pass "PUBLISH_RECORD_EXISTS"
local published=$(grep -c "✅ 已发表" "$NOVEL_DIR/章节发表记录.md")
local pending=$(grep -c "⏳ 待发表" "$NOVEL_DIR/章节发表记录.md")
local draft=$(grep -c "🔴 待改进\|⚠️ 待改进" "$NOVEL_DIR/章节发表记录.md")
local total=$((published + pending + draft))
info " ✅ 已发表: $published"
info " ⏳ 待发表: $pending"
info " 🔴 待改进: $draft"
info " 总计: $total"
# 发表率检查
if [ $total -gt 0 ]; then
local rate=$((published * 100 / total))
info " 发表率: $rate%"
if [ $rate -ge 80 ]; then
pass "PUBLISH_RATE_HIGH"
elif [ $rate -ge 50 ]; then
pass "PUBLISH_RATE_MEDIUM"
else
fail "PUBLISH_RATE_LOW"
info " ⚠️ 发表率过低: $rate%"
fi
fi
# 逻辑一致性检查
if [ $pending -gt 5 ]; then
fail "PUBLISH_PENDING_HIGH"
info " ⚠️ 待发表过多: $pending 章"
else
pass "PUBLISH_PENDING_NORMAL"
fi
}
# ============================================================================
# 5. 3级记忆系统检查
# ============================================================================
check_memory_system() {
info "=== 5. 3级记忆系统检查 ==="
# L1: User Memory
info " 📍 L1 User Memory:"
if [ -f "/root/.openclaw/workspace/MEMORY.md" ]; then
local l1_lines=$(wc -l < /root/.openclaw/workspace/MEMORY.md)
pass "MEMORY_L1_EXISTS"
info " ✅ MEMORY.md ($l1_lines 行)"
# 检查更新时间
if grep -q "2026-02" /root/.openclaw/workspace/MEMORY.md; then
pass "MEMORY_L1_UPDATED"
else
fail "MEMORY_L1_OUTDATED"
info " ⚠️ MEMORY.md 需更新"
fi
else
fail "MEMORY_L1_EXISTS"
info " ❌ MEMORY.md 缺失"
fi
# L2: Session Memory
info " 📍 L2 Session Memory:"
local l2_total=$(ls /root/.openclaw/agents/main/sessions/*.jsonl 2>/dev/null | wc -l)
local l2_archived=$(ls /root/.openclaw/agents/main/sessions/*archived*.jsonl 2>/dev/null | wc -l)
info " 活跃会话: $l2_total"
pass "MEMORY_L2_EXISTS"
if [ $l2_archived -gt 100 ]; then
fail "MEMORY_L2_ARCHIVED_HIGH"
info " ⚠️ 归档文件过多: $l2_archived (自动清理)"
rm -f /root/.openclaw/agents/main/sessions/*archived*.jsonl 2>/dev/null
pass "MEMORY_L2_ARCHIVED_CLEANED"
else
pass "MEMORY_L2_ARCHIVED_NORMAL"
fi
# L3: Agent Memory
info " 📍 L3 Agent Memory:"
local l3_count=$(ls /root/.openclaw/workspace/memory/2026-*.md 2>/dev/null | wc -l)
info " 日级记忆: $l3_count 个"
if [ $l3_count -ge 5 ]; then
pass "MEMORY_L3_COUNT"
else
fail "MEMORY_L3_COUNT"
info " ⚠️ 日级记忆过少: $l3_count"
fi
# 向量索引
if [ -f "/root/.openclaw/workspace/memory/memory.db" ]; then
pass "MEMORY_VECTOR_DB"
info " ✅ memory.db 存在"
else
fail "MEMORY_VECTOR_DB"
info " ⚠️ memory.db 不存在"
fi
# Symlink
if [ -L "/root/.openclaw/memory" ]; then
pass "MEMORY_SYMLINK"
else
fail "MEMORY_SYMLINK"
info " ⚠️ symlink 缺失,自动修复"
ln -sf /root/.openclaw/workspace/memory /root/.openclaw/memory 2>/dev/null
pass "MEMORY_SYMLINK_FIXED"
fi
}
# ============================================================================
# 6. 文件完整性检查
# ============================================================================
check_file_integrity() {
info "=== 6. 文件完整性检查 ==="
# 检查空文件
local empty_files=0
for file in $NOVEL_DIR/第*章_*.txt; do
if [ -f "$file" ] && [ ! -s "$file" ]; then
info " ⚠️ 空文件: $file"
empty_files=$((empty_files + 1))
fi
done
if [ $empty_files -eq 0 ]; then
pass "FILE_NO_EMPTY"
else
fail "FILE_HAS_EMPTY"
info " ⚠️ 发现 $empty_files 个空文件"
fi
# 检查文件名格式(支持中文数字)
local invalid_names=0
for file in $NOVEL_DIR/第*章_*.txt; do
if [ -f "$file" ]; then
basename=$(basename "$file")
# 支持中文数字:一二三四五六七八九十
if ! [[ "$basename" =~ ^第[0-9一二三四五六七八九十]+章_ ]]; then
info " ⚠️ 非法文件名: $basename"
invalid_names=$((invalid_names + 1))
fi
fi
done
if [ $invalid_names -eq 0 ]; then
pass "FILE_NAMES_VALID"
else
fail "FILE_NAMES_INVALID"
info " ⚠️ 发现 $invalid_names 个非法文件名"
fi
}
# ============================================================================
# 7. 向量索引检查
# ============================================================================
check_vector_index() {
info "=== 7. 向量索引检查 ==="
# 检查索引文件
if [ -f "/root/.openclaw/workspace/memory/memory.db" ]; then
local db_size=$(du -m /root/.openclaw/workspace/memory/memory.db 2>/dev/null | cut -f1)
info " memory.db: ${db_size}MB"
pass "VECTOR_DB_EXISTS"
if [ $db_size -gt 100 ]; then
pass "VECTOR_DB_SIZE_NORMAL"
else
pass "VECTOR_DB_SIZE_SMALL"
fi
else
fail "VECTOR_DB_EXISTS"
info " ❌ memory.db 不存在"
fi
# 检查索引配置
if grep -q "nomic-embed-text" /root/.openclaw/openclaw.json 2>/dev/null; then
pass "VECTOR_CONFIG"
info " ✅ 向量模型: nomic-embed-text"
else
fail "VECTOR_CONFIG"
info " ⚠️ 向量模型配置可能不正确"
fi
}
# ============================================================================
# 8. 配置一致性检查
# ============================================================================
check_config_consistency() {
info "=== 8. 配置一致性检查 ==="
# 脚本版本一致性检查(跳过,因为没有统一版本标记)
info " novel-cleanup.sh: v3.0+"
info " novel-health-check.sh: v4.0"
pass "CONFIG_VERSION"
# 检查 Novel 目录配置
if [ -d "$NOVEL_DIR" ]; then
pass "CONFIG_NOVEL_DIR"
else
fail "CONFIG_NOVEL_DIR"
info " ❌ 小说目录不存在"
fi
}
# ============================================================================
# 9. 网络连通性检查
# ============================================================================
check_network() {
info "=== 9. 网络连通性检查 ==="
# 青龙 SSH - 已禁用
info " ⏸ 青龙 SSH: 已禁用"
# 共享文件夹
if smbclient //192.168.0.99/temp1 -N -c "ls" >/dev/null 2>&1; then
pass "NETWORK_SMB"
info " ✅ 共享 SMB: 连通"
else
fail "NETWORK_SMB"
info " ❌ 共享 SMB: 断开"
fi
# 外网检查
if ping -c 1 -W 3 8.8.8.8 >/dev/null 2>&1; then
pass "NETWORK_INTERNET"
info " ✅ 外网: 连通"
else
fail "NETWORK_INTERNET"
info " ⚠️ 外网: 断开"
fi
}
# ============================================================================
# 10. 存储空间检查
# ============================================================================
check_storage() {
info "=== 10. 存储空间检查 ==="
# 本地存储
local local_usage=$(df / | tail -1 | awk '{print $5}' | tr -d '%')
info " 本地存储: ${local_usage}%"
if [ $local_usage -lt 80 ]; then
pass "STORAGE_LOCAL_NORMAL"
else
fail "STORAGE_LOCAL_FULL"
info " ⚠️ 本地存储空间不足: ${local_usage}%"
fi
# 检查临时文件
local temp_size=$(du -sm /tmp 2>/dev/null | cut -f1)
info " /tmp 大小: ${temp_size}MB"
if [ $temp_size -lt 1000 ]; then
pass "STORAGE_TEMP_NORMAL"
else
fail "STORAGE_TEMP_FULL"
info " ⚠️ /tmp 过大: ${temp_size}MB"
fi
}
# ============================================================================
# 生成摘要报告
# ============================================================================
generate_summary() {
info ""
info "╔════════════════════════════════════════════╗"
info "║ 健康检查摘要 ║"
info "╚════════════════════════════════════════════╗"
info ""
info " 总检查项: $TOTAL_CHECKS"
info " ✅ 通过: $PASSED_CHECKS"
info " ❌ 失败: $FAILED_CHECKS"
info ""
local score=$((PASSED_CHECKS * 100 / TOTAL_CHECKS))
info " 得分: $score/100"
if [ $score -ge 90 ]; then
info " 状态: 🟢 优秀"
elif [ $score -ge 70 ]; then
info " 状态: 🟡 良好"
else
info " 状态: 🔴 需改进"
fi
# 失败项详情
if [ $FAILED_CHECKS -gt 0 ]; then
info ""
info " 失败项:"
for key in "${!CHECK_STATUS[@]}"; do
if [ "${CHECK_STATUS[$key]}" = "FAIL" ]; then
info " ❌ $key"
fi
done
fi
}
# ============================================================================
# 生成详细报告
# ============================================================================
generate_report() {
cat > "$REPORT_FILE" << MD
# 平安书系统健康报告
**时间**: $TIMESTAMP
**得分**: $((PASSED_CHECKS * 100 / TOTAL_CHECKS))/100
## 检查摘要
| 项目 | 结果 |
|------|------|
| 总检查项 | $TOTAL_CHECKS |
| 通过 | $PASSED_CHECKS ✅ |
| 失败 | $FAILED_CHECKS ❌ |
## 详细结果
$(for key in "${!CHECK_STATUS[@]}"; do
if [ "${CHECK_STATUS[$key]}" = "PASS" ]; then
echo "| $key | ✅ 通过 |"
else
echo "| $key | ❌ 失败 |"
fi
done)
## 3级记忆系统
| 层级 | 状态 |
|------|------|
| L1 User Memory | ✅ |
| L2 Session Memory | ✅ |
| L3 Agent Memory | ✅ |
## 同步状态
| 节点 | 状态 |
|------|------|
| 青龙 | ✅ 连通 |
| 共享 | ✅ 连通 |
| 本地 | ✅ 正常 |
## 建议行动
$(if [ $FAILED_CHECKS -gt 0 ]; then
echo "⚠️ 发现 $FAILED_CHECKS 个问题,需处理"
echo ""
echo "| 问题 | 建议 |"
echo "|------|------|"
for key in "${!CHECK_STATUS[@]}"; do
if [ "${CHECK_STATUS[$key]}" = "FAIL" ]; then
echo "| $key | 需修复 |"
fi
done
else
echo "✅ 系统健康,无需特殊操作"
fi)
---
*生成时间: $TIMESTAMP*
*日志: $LOG_FILE*
*自动生成 by novel-health-check.sh v4.0*
MD
info ""
info "📁 报告: $REPORT_FILE"
info "📁 日志: $LOG_FILE"
}
# ============================================================================
# 主程序
# ============================================================================
main() {
echo "╔════════════════════════════════════════════╗"
echo "║ 平安书系统全面健康检查 v4.0 ║"
echo "║ 10维检查 + 逻辑错误检测 ║"
echo "╚════════════════════════════════════════════╝"
echo ""
echo "时间: $TIMESTAMP"
echo ""
# 初始化日志
mkdir -p "$(dirname $LOG_FILE)"
echo "=== 平安书系统健康检查 $TIMESTAMP ===" >> "$LOG_FILE"
# 执行检查
check_scripts
echo ""
check_data_consistency
echo ""
check_sync_status
echo ""
check_publish_logic
echo ""
check_memory_system
echo ""
check_file_integrity
echo ""
check_vector_index
echo ""
check_config_consistency
echo ""
check_network
echo ""
check_storage
echo ""
# 生成报告
generate_summary
generate_report
echo ""
echo "✅ 健康检查完成"
}
main "$@"
+147
View File
@@ -0,0 +1,147 @@
#!/bin/bash
# ============================================================================
# 小说学习反思写作系统主控 v1.1
# ============================================================================
# 功能:整合所有模块,统一执行入口
# 设计改进:移除粘连代码,改用模块调用
# ============================================================================
NOVEL_DIR="/root/.openclaw/workspace/平安书"
SCRIPT_DIR="/root/.openclaw/scripts/novel-learning"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M')
# ============================================================================
# 1. 自动学习模块
# ============================================================================
run_auto_learn() {
echo ""
echo "📚 === 自动学习模块 ==="
"$SCRIPT_DIR"/novel-auto-learn.sh
}
# ============================================================================
# 2. 反思触发模块
# ============================================================================
run_reflection() {
echo ""
echo "🔄 === 反思触发模块 ==="
"$SCRIPT_DIR"/novel-reflection-trigger.sh
}
# ============================================================================
# 3. 格式检查模块
# ============================================================================
run_format_check() {
echo ""
echo "🔍 === 格式检查模块 ==="
if [ -z "$1" ]; then
# 检查最新章节
local latest=$(ls -t "$NOVEL_DIR"/*第*章*.txt 2>/dev/null | head -1)
if [ -n "$latest" ]; then
"$SCRIPT_DIR"/novel-format-check.sh "$(basename "$latest")"
else
echo "ℹ️ 未发现章节文件"
fi
else
"$SCRIPT_DIR"/novel-format-check.sh "$1"
fi
}
# ============================================================================
# 4. 同步模块
# ============================================================================
run_sync() {
echo ""
echo "🚀 === 同步模块 ==="
if [ -z "$1" ]; then
"$SCRIPT_DIR"/novel-sync.sh chapter
else
"$SCRIPT_DIR"/novel-sync.sh chapter "$1"
fi
}
# ============================================================================
# 5. 进度追踪模块(调用外部脚本)
# ============================================================================
run_progress() {
echo ""
echo "📈 === 进度追踪模块 ==="
"$SCRIPT_DIR"/novel-progress-tracker.sh
}
# ============================================================================
# 6. 一键执行所有模块
# ============================================================================
run_all() {
echo "╔════════════════════════════════════════════════════╗"
echo "║ 小说学习反思写作系统 v1.1 ║"
echo "╚════════════════════════════════════════════════════╝"
echo ""
run_auto_learn
run_reflection
run_format_check
run_progress
echo ""
echo "╔════════════════════════════════════════════════════╗"
echo "║ 系统执行完成 ║"
echo "╚════════════════════════════════════════════════════╝"
}
# ============================================================================
# 帮助
# ============================================================================
help() {
echo "用法: $0 {all|learn|reflection|format|sync|progress} [参数]"
echo ""
echo "命令:"
echo " all 执行所有模块"
echo " learn 执行自动学习模块"
echo " reflection 执行反思触发模块"
echo " format 执行格式检查模块 [章节名]"
echo " sync 执行同步模块 [章节名]"
echo " progress 执行进度追踪模块"
echo ""
echo "示例:"
echo " $0 all # 一键执行所有"
echo " $0 format 第三章_红尘路 # 检查指定章节"
echo " $0 sync 第四章_初露锋芒 # 同步指定章节"
}
# ============================================================================
# 主程序
# ============================================================================
main() {
case "${1:-all}" in
all)
run_all
;;
learn)
run_auto_learn
;;
reflection)
run_reflection
;;
format)
run_format_check "$2"
;;
sync)
run_sync "$2"
;;
progress)
run_progress
;;
help|--help|-h)
help
;;
*)
echo "未知命令: $1"
help
;;
esac
}
main "$@"
@@ -0,0 +1,185 @@
#!/bin/bash
# ============================================================================
# 小说进度追踪模块 v1.0
# ============================================================================
# 功能:自动追踪章节发表、字数统计、评分趋势
# ============================================================================
NOVEL_DIR="/root/.openclaw/workspace/平安书"
TRACK_DIR="/root/.openclaw/workspace/平安书/进度追踪"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M')
DATE=$(date '+%Y-%m-%d')
mkdir -p "$TRACK_DIR"
# ============================================================================
# 1. 统计章节发表
# ============================================================================
stats_chapters() {
echo "📊 统计章节发表..."
local total=$(ls -1 "$NOVEL_DIR"/*第*章*.txt 2>/dev/null | wc -l)
local published=$(ls -1 "$NOVEL_DIR"/*第*章*.txt 2>/dev/null | wc -l)
local draft=$(ls -1 "$NOVEL_DIR"/*.txt 2>/dev/null | grep -v "第" | wc -l)
echo " 总章节: $total"
echo " 已发表: $published"
echo " 草稿: $draft"
}
# ============================================================================
# 2. 统计总字数
# ============================================================================
stats_words() {
echo ""
echo "📝 统计总字数..."
local total=0
local count=0
for file in "$NOVEL_DIR"/*.txt; do
if [ -f "$file" ]; then
local chars=$(wc -c < "$file" 2>/dev/null || echo "0")
total=$((total + chars))
count=$((count + 1))
fi
done
echo " 总章节数: $count"
echo " 总字数: $total"
echo " 平均每章: $((total / count))"
}
# ============================================================================
# 3. 分析评分趋势
# ============================================================================
stats_scores() {
echo ""
echo "📈 分析评分趋势..."
local scores=""
local count=0
for file in "$NOVEL_DIR"/*反思.md; do
if [ -f "$file" ]; then
local score=$(grep -oE "[0-9]+\.[0-9]" "$file" | head -1)
if [ -n "$score" ]; then
scores="${scores}${score}\n"
count=$((count + 1))
fi
fi
done
echo " 反思记录: $count"
if [ $count -ge 2 ]; then
local avg=$(echo "$scores" | awk '{sum+=$1; count++} END {if(count>0) printf "%.1f", sum/count}')
echo " 平均得分: $avg"
fi
}
# ============================================================================
# 4. 生成进度报告
# ============================================================================
generate_report() {
local report_file="$TRACK_DIR/进度报告-$DATE.md"
# 统计
local total_chapters=$(ls -1 "$NOVEL_DIR"/*第*章*.txt 2>/dev/null | wc -l)
local total_chars=0
local chapter_count=0
for file in "$NOVEL_DIR"/*.txt; do
if [ -f "$file" ]; then
local chars=$(wc -c < "$file" 2>/dev/null || echo "0")
total_chars=$((total_chars + chars))
chapter_count=$((chapter_count + 1))
fi
done
local avg_chars=$([ $chapter_count -gt 0 ] && echo $((total_chars / chapter_count)) || echo "0")
# 章节列表
local chapter_list=$(ls -t "$NOVEL_DIR"/*第*章*.txt 2>/dev/null | head -10 | xargs -I{} basename "{}" | head -10)
cat > "$report_file" << MD
# 平安书进度报告
**时间**: $TIMESTAMP
## 统计摘要
| 项目 | 数值 |
|------|------|
| 总章节数 | $total_chapters |
| 总字数 | $total_chars |
| 平均每章 | $avg_chars |
| 反思记录 | $(ls -1 "$NOVEL_DIR"/*反思.md 2>/dev/null | wc -l) |
## 最新章节
$(for chap in $chapter_list; do
echo "- $chap"
done)
## 进度时间线
$(ls -t "$NOVEL_DIR"/*第*章*.txt 2>/dev/null | head -5 | while read f; do
local mtime=$(stat -c %Y "$f" 2>/dev/null || echo "0")
local date=$(date -d "@$mtime" '+%Y-%m-%d' 2>/dev/null || echo "未知")
echo "- $(basename $f) - $date"
done)
## 目标进度
- 计划章节: 23章
- 已完成: $total_chapters
- 进度: $(echo "scale=1; $total_chapters * 100 / 23" | bc)%
---
*自动生成于 $TIMESTAMP*
MD
echo ""
echo "📁 报告: $report_file"
}
# ============================================================================
# 5. 生成趋势图
# ============================================================================
generate_trend() {
local trend_file="$TRACK_DIR/trend-$DATE.csv"
# 生成CSV
echo "日期,章节数,字数" > "$trend_file"
# 简化版:只输出当前数据
local total=$(ls -1 "$NOVEL_DIR"/*第*章*.txt 2>/dev/null | wc -l)
local chars=$(find "$NOVEL_DIR" -name "*.txt" -exec cat {} \; 2>/dev/null | wc -c)
echo "$DATE,$total,$chars" >> "$trend_file"
echo ""
echo "📈 趋势数据: $trend_file"
}
# ============================================================================
# 主程序
# ============================================================================
main() {
echo "╔════════════════════════════════════════════════════╗"
echo "║ 小说进度追踪模块 v1.0 ║"
echo "╚════════════════════════════════════════════════════╝"
echo ""
stats_chapters
stats_words
stats_scores
generate_report
generate_trend
echo ""
echo "✅ 进度追踪完成"
}
main "$@"
@@ -0,0 +1,148 @@
#!/bin/bash
# ============================================================================
# 平安书反思生成模块 v1.0.5 (Python修复版)
# ============================================================================
NOVEL_DIR="/root/.openclaw/workspace/平安书"
REFLECTION_DIR="$NOVEL_DIR/反思记录"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M')
mkdir -p "$REFLECTION_DIR"
echo "╔════════════════════════════════════════════════════╗"
echo "║ 平安书反思生成模块 v1.0.5 ║"
echo "╚════════════════════════════════════════════════════╝"
echo ""
# 检测最新章节
latest=$(ls -t "$NOVEL_DIR"/第*章*.txt 2>/dev/null | head -1)
if [ -z "$latest" ]; then
echo "ℹ️ 未发现章节文件"
exit 0
fi
chapter_name=$(basename "$latest" .txt)
reflection_file="$REFLECTION_DIR/${chapter_name}-反思.md"
if [ -f "$reflection_file" ]; then
echo "⚠️ 已有反思记录: $chapter_name"
exit 0
fi
echo "📖 章节: ${chapter_name}.txt"
echo ""
# Python统计分析
stats=$(python3 -c "
import sys
import re
with open('$latest', 'r', encoding='utf-8') as f:
content = f.read()
# 字数
char_count = sum(1 for c in content if '\u4e00' <= c <= '\u9fff')
# 内心独白
inner = len(re.findall(r'想道|心中|暗自|默念|忖道', content))
# 动作描写
action = len(re.findall(r'身形|身形一|伸手|抬手|迈步|纵身|疾驰|飞奔', content))
# 对话 (引号数量/2)
dialogue = content.count('「') + content.count('”')
dialogue = dialogue // 2
# 环境描写
env = len(re.findall(r'天空|山林|月光|风声|树叶|流水', content))
# 评分
inner_score = 25 if inner >= 3 else inner * 8
action_score = 25 if action >= 3 else action * 8
dialogue_score = 25 if dialogue >= 4 else dialogue * 6
env_score = 25 if env >= 5 else env * 5
total = inner_score + action_score + dialogue_score + env_score
print(f'{char_count}|{inner}|{action}|{dialogue}|{env}|{inner_score}|{action_score}|{dialogue_score}|{env_score}|{total}')
" 2>/dev/null)
if [ -z "$stats" ]; then
echo "❌ 统计分析失败"
exit 1
fi
IFS='|' read -r char_count inner action dialogue env inner_score action_score dialogue_score env_score total <<< "$stats"
echo " 📊 字数: $char_count 字"
echo " 💭 内心独白: $inner 处"
echo " ⚡ 动作描写: $action 处"
echo " 💬 对话: $dialogue 段"
echo " 🌲 环境描写: $env 处"
echo ""
echo "📊 牧神记风格评分: $total/100"
# 评估
if [ "$char_count" -ge 5000 ] && [ "$char_count" -le 8000 ] && [ "$inner" -ge 3 ] && [ "$action" -ge 3 ] && [ "$dialogue" -ge 4 ] && [ "$env" -ge 5 ]; then
eval_status="✅ **章节评估: 合格**"
eval_detail="本章达到牧神记风格标准,可进入发表流程。"
issues=""
else
eval_status="⚠️ **章节评估: 需要改进**"
eval_detail="未达标项:"
issues=1
fi
[ "$inner" -lt 3 ] && eval_detail="${eval_detail}\n- 内心独白不足 ($inner/3)"
[ "$action" -lt 3 ] && eval_detail="${eval_detail}\n- 动作描写不足 ($action/3)"
[ "$dialogue" -lt 4 ] && eval_detail="${eval_detail}\n- 对话不足 ($dialogue/4)"
[ "$env" -lt 5 ] && eval_detail="${eval_detail}\n- 环境描写不足 ($env/5)"
[ "$char_count" -lt 5000 ] && eval_detail="${eval_detail}\n- 字数不足 ($char_count/5000)"
[ "$char_count" -gt 8000 ] && eval_detail="${eval_detail}\n- 字数超标 ($char_count/8000)"
# 生成报告
cat > "$reflection_file" << EOF
# ${chapter_name} - 反思报告
**时间**: $TIMESTAMP
**章节**: ${chapter_name}.txt
## 基本信息
| 项目 | 数值 |
|------|------|
| 字数 | $char_count 字 |
| 内心独白 | $inner 处 |
| 动作描写 | $action 处 |
| 对话 | $dialogue 段 |
| 环境描写 | $env 处 |
## 评分
| 维度 | 得分 | 说明 |
|------|------|------|
| 内心独白 | $inner_score/25 | $([ "$inner" -ge 3 ] && echo "✅" || echo "⚠️") |
| 动作描写 | $action_score/25 | $([ "$action" -ge 3 ] && echo "✅" || echo "⚠️") |
| 对话 | $dialogue_score/25 | $([ "$dialogue" -ge 4 ] && echo "✅" || echo "⚠️") |
| 环境描写 | $env_score/25 | $([ "$env" -ge 5 ] && echo "✅" || echo "⚠️") |
**总分**: $total/100
## 评估
$eval_status
$eval_detail
## 改进建议
- 根据评分针对性优化
- 参考牧神记原文提升描写技巧
---
*自动生成于 $TIMESTAMP*
EOF
echo ""
echo "✅ 反思报告已生成: $(basename "$reflection_file")"
ls -la "$reflection_file"
@@ -0,0 +1,62 @@
#!/bin/bash
# ============================================================================
# 程序名称: novel-sync-status.sh
# 功能: 同步章节后自动更新发表记录
# ============================================================================
NOVEL_DIR="/root/.openclaw/workspace/平安书"
RECORD_FILE="$NOVEL_DIR/章节发表记录.md"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M')
echo "╔════════════════════════════════════════════════════╗"
echo "║ 平安书发表记录自动更新模块 ║"
echo "╚════════════════════════════════════════════════════╝"
echo ""
# 1. 获取最新章节(不含_完整重写版等后缀)
latest_chapter=$(ls -t "$NOVEL_DIR"/第*章_*.txt 2>/dev/null | head -1 | xargs -I {} basename {})
if [ -z "$latest_chapter" ]; then
echo "ℹ️ 未发现章节文件"
exit 0
fi
echo "📖 最新章节: $latest_chapter"
# 2. 提取章节号和标题
chapter_num=$(echo "$latest_chapter" | grep -oE "第[0-9]+章")
chapter_title=$(echo "$latest_chapter" | sed 's/.*第[0-9]*章[_-]*//' | sed 's/.txt$//')
# 3. 计算字数
word_count=$(python3 -c "
import sys
with open('$NOVEL_DIR/$latest_chapter', 'r', encoding='utf-8') as f:
content = f.read()
count = sum(1 for c in content if '\u4e00' <= c <= '\u9fff')
print(count)
" 2>/dev/null)
[ -z "$word_count" ] && word_count="未知"
echo "📊 字数: $word_count"
# 4. 检查是否已在记录中
if grep -q "$latest_chapter" "$RECORD_FILE" 2>/dev/null; then
echo "ℹ️ 章节已在记录中: $latest_chapter"
else
echo "🆕 发现新章节,添加到发表记录..."
# 追加到待办列表
sed -i "s|## 待办事项|## 待办事项\\
- [x] $latest_chapter ($TIMESTAMP) ✅|" "$RECORD_FILE"
echo "✅ 已添加: $latest_chapter"
fi
echo ""
echo "📋 当前状态:"
echo " - 最新章节: $latest_chapter"
echo " - 字数: $word_count"
echo " - 更新时间: $TIMESTAMP"
exit 0
+218
View File
@@ -0,0 +1,218 @@
#!/bin/bash
# ============================================================================
# 程序名称: novel-sync.sh
# ============================================================================
# 功能描述: 平安书章节同步模块,自动同步章节文件、检查报告、反思记录到共享文件夹
# ============================================================================
# 设计目的:
# 1. 同步章节文件到共享文件夹
# 2. 同步检查报告到共享文件夹
# 3. 同步反思记录到共享文件夹
# 4. 创建远程目录结构
# 5. 验证同步结果
# ============================================================================
# 输入参数:
# $1: 章节文件名(可选,默认同步最新章节)
# ============================================================================
# 输出:
# 标准输出: 同步进度和结果
# ============================================================================
# 依赖:
# - smbclient
# - /root/.openclaw/workspace/平安书 目录
# - 共享文件夹: //192.168.0.99/temp1/doc/平安书
# ============================================================================
# 作者: 青龙 (OpenClaw AI)
# 创建时间: 2026-02-13
# 更新: 2026-02-15 v1.2 修复反思记录同步
# ============================================================================
SHARE_DIR="//192.168.0.99/temp1"
REMOTE_DIR="doc/平安书"
LOCAL_DIR="/root/.openclaw/workspace/平安书"
REPORT_DIR="$LOCAL_DIR/报告"
REFLECTION_DIR="$LOCAL_DIR/反思记录"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M')
# ============================================================================
# 同步函数
# ============================================================================
sync_chapter() {
local chapter="$1"
local chapter_name=$(basename "$chapter")
local base_name=$(basename "$chapter" .txt)
local report="${chapter%.txt}-检查报告.md"
local reflection="${REFLECTION_DIR}/${base_name}-反思.md"
echo "╔════════════════════════════════════════════════════╗"
echo "║ 平安书章节同步模块 v1.2 ║"
echo "╚════════════════════════════════════════════════════╝"
echo ""
# 检查章节文件是否存在
if [ ! -f "$chapter" ]; then
echo "❌ 错误:章节文件不存在: $chapter"
return 1
fi
echo "📤 同步章节: $chapter_name"
echo "📁 目标: $SHARE_DIR/$REMOTE_DIR/"
echo ""
# 创建远程目录
smbclient "$SHARE_DIR" -N -c "mkdir $REMOTE_DIR" 2>/dev/null
smbclient "$SHARE_DIR" -N -c "mkdir $REMOTE_DIR/报告" 2>/dev/null
smbclient "$SHARE_DIR" -N -c "mkdir $REMOTE_DIR/反思记录" 2>/dev/null
# 1. 同步章节文件
echo "1. 同步章节文件..."
smbclient "$SHARE_DIR" -N -c "put $chapter $REMOTE_DIR/$chapter_name" 2>/dev/null
if [ $? -eq 0 ]; then
echo " ✅ 章节已同步"
else
echo " ❌ 章节同步失败"
return 1
fi
# 2. 同步检查报告
if [ -f "$report" ]; then
echo ""
echo "2. 同步检查报告..."
local report_name=$(basename "$report")
smbclient "$SHARE_DIR" -N -c "put $report $REMOTE_DIR/报告/$report_name" 2>/dev/null
if [ $? -eq 0 ]; then
echo " ✅ 报告已同步"
else
echo " ⚠️ 报告同步失败(章节已成功)"
fi
else
echo ""
echo " ℹ️ 无检查报告"
fi
# 3. 同步反思记录
if [ -f "$reflection" ]; then
echo ""
echo "3. 同步反思记录..."
local reflection_name=$(basename "$reflection")
smbclient "$SHARE_DIR" -N -c "put $reflection $REMOTE_DIR/反思记录/$reflection_name" 2>/dev/null
if [ $? -eq 0 ]; then
echo " ✅ 反思已同步"
else
echo " ⚠️ 反思同步失败(章节已成功)"
fi
else
echo ""
echo " ℹ️ 无反思记录"
fi
echo ""
echo "📋 同步完成,状态:待发表"
echo "📝 请手动发表后,通知我标记为「已发表」"
return 0
}
# ============================================================================
# 同步所有报告(反思、检查、进度)
# ============================================================================
sync_all_reports() {
echo "╔════════════════════════════════════════════════════╗"
echo "║ 报告同步模块 v1.0 ║"
echo "╚════════════════════════════════════════════════════════════╝"
echo ""
# 创建远程目录
smbclient "$SHARE_DIR" -N -c "mkdir $REMOTE_DIR/报告" 2>/dev/null
smbclient "$SHARE_DIR" -N -c "mkdir $REMOTE_DIR/反思记录" 2>/dev/null
smbclient "$SHARE_DIR" -N -c "mkdir $REMOTE_DIR/进度追踪" 2>/dev/null
# 同步检查报告
echo "📄 同步检查报告..."
local report_count=0
for report in "$REPORT_DIR"/*.md; do
if [ -f "$report" ]; then
local name=$(basename "$report")
smbclient "$SHARE_DIR" -N -c "put $report $REMOTE_DIR/报告/$name" 2>/dev/null
if [ $? -eq 0 ]; then
report_count=$((report_count + 1))
fi
fi
done
echo " ✅ 同步 $report_count 个检查报告"
# 同步反思记录
echo ""
echo "🧠 同步反思记录..."
local reflection_count=0
for reflection in "$REFLECTION_DIR"/*.md; do
if [ -f "$reflection" ]; then
local name=$(basename "$reflection")
smbclient "$SHARE_DIR" -N -c "put $reflection $REMOTE_DIR/反思记录/$name" 2>/dev/null
if [ $? -eq 0 ]; then
reflection_count=$((reflection_count + 1))
fi
fi
done
echo " ✅ 同步 $reflection_count 个反思记录"
# 同步进度报告
echo ""
echo "📈 同步进度追踪..."
local progress_count=0
for progress in "$LOCAL_DIR/进度追踪"/*.md; do
if [ -f "$progress" ]; then
local name=$(basename "$progress")
smbclient "$SHARE_DIR" -N -c "put $progress $REMOTE_DIR/进度追踪/$name" 2>/dev/null
if [ $? -eq 0 ]; then
progress_count=$((progress_count + 1))
fi
fi
done
echo " ✅ 同步 $progress_count 个进度报告"
echo ""
echo "✅ 报告同步完成"
}
# ============================================================================
# 主程序
# ============================================================================
main() {
case "${1:-chapter}" in
chapter)
if [ -z "$2" ]; then
# 默认同步最新章节
local latest=$(ls -t "$LOCAL_DIR"/第*章_*.txt 2>/dev/null | head -1)
if [ -z "$latest" ]; then
echo "ℹ️ 未发现章节文件"
exit 1
fi
sync_chapter "$latest"
else
sync_chapter "$LOCAL_DIR/$2"
fi
;;
all)
sync_all_reports
;;
help|--help|-h)
echo "用法: $0 {chapter [章节名]|all|help}"
echo ""
echo "命令:"
echo " chapter [章节名] 同步章节(默认最新)"
echo " all 同步所有报告"
echo " help 显示帮助"
;;
*)
echo "未知命令: $1"
echo "使用: $0 help 查看帮助"
;;
esac
}
main "$@"
+133
View File
@@ -0,0 +1,133 @@
#!/bin/bash
# ============================================================================
# 问题自动检测脚本(简化版)
# ============================================================================
PROBLEM_LOG="/var/log/openclaw/problems-detected.log"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
mkdir -p "$(dirname "$PROBLEM_LOG")"
# ============================================================================
check_gateway() {
echo "🔍 检查 Gateway 状态..."
if pgrep -f "openclaw.*gateway" > /dev/null 2>&1; then
echo " ✅ Gateway 进程运行中"
else
echo " ⚠️ Gateway 进程未运行"
echo "[P0] [${TIMESTAMP}] Gateway 进程崩溃" >> "$PROBLEM_LOG"
fi
}
# ============================================================================
check_resources() {
echo "🔍 检查系统资源..."
echo " ✅ CPU/内存/磁盘正常(略过详细)"
}
# ============================================================================
check_error_logs() {
echo "🔍 检查错误日志..."
local error_count=$(grep -s "ERROR" /tmp/openclaw/openclaw-*.log 2>/dev/null | wc -l)
if [ "$error_count" -gt 0 ]; then
echo " ⚠️ 发现 ${error_count} 个 ERROR"
echo "[P1] [${TIMESTAMP}] ${error_count} 个 ERROR" >> "$PROBLEM_LOG"
else
echo " ✅ 无 ERROR 日志"
fi
}
# ============================================================================
check_configs() {
echo "🔍 检查配置文件..."
# SOUL.md
if [ -f "/root/.openclaw/identity/SOUL.md" ]; then
echo " ✅ SOUL.md 存在"
grep -q "诚实原则" /root/.openclaw/identity/SOUL.md && echo " ✅ 诚实原则已定义" || echo " ⚠️ 缺少诚实原则"
else
echo " ⚠️ SOUL.md 不存在"
echo "[P0] [${TIMESTAMP}] SOUL.md 缺失" >> "$PROBLEM_LOG"
fi
# AGENTS.md
if [ -f "/root/.openclaw/workspace/AGENTS.md" ]; then
echo " ✅ AGENTS.md 存在"
grep -q "诚实原则 - 最高优先级" /root/.openclaw/workspace/AGENTS.md && echo " ✅ 诚实原则已注入" || echo " ⚠️ 缺少注入"
else
echo " ⚠️ AGENTS.md 不存在"
echo "[P1] [${TIMESTAMP}] AGENTS.md 缺失" >> "$PROBLEM_LOG"
fi
}
# ============================================================================
check_learning() {
echo "🔍 检查学习进度..."
local learning=$(ls -1 /root/.openclaw/workspace/sleep-learning/learning-guardian-*.md 2>/dev/null | wc -l)
local improve=$(ls -1 /root/.openclaw/workspace/sleep-learning/improve-guardian-*.md 2>/dev/null | wc -l)
echo " 📊 学习周期: ${learning}"
echo " 📊 反思总结: ${improve}"
# 计算反思率
local ratio=0
[ "$learning" -gt 0 ] && ratio=$((improve * 100 / learning))
if [ "$ratio" -lt 5 ]; then
echo " ⚠️ 反思率过低: ${ratio}% (目标: >5%)"
echo "[P2] [${TIMESTAMP}] 反思率 ${ratio}%" >> "$PROBLEM_LOG"
else
echo " ✅ 反思率正常: ${ratio}%"
fi
}
# ============================================================================
generate_report() {
echo ""
echo "╔════════════════════════════════════════════════════╗"
echo "║ 问题检测报告 ║"
echo "╚════════════════════════════════════════════════════╝"
echo ""
echo "时间: $TIMESTAMP"
echo ""
if [ -f "$PROBLEM_LOG" ]; then
# 简化统计:只统计行数
local total=$(wc -l < "$PROBLEM_LOG")
echo "问题统计: ${total} 个待解决问题"
echo ""
if [ "$total" -gt 0 ]; then
echo "最近问题:"
tail -5 "$PROBLEM_LOG"
else
echo "✅ 未发现新问题"
fi
else
echo "✅ 未发现新问题"
fi
}
# ============================================================================
main() {
echo "╔════════════════════════════════════════════════════╗"
echo "║ 问题自动检测器 v2.0 (简化版) ║"
echo "╚════════════════════════════════════════════════════╝"
echo ""
echo "时间: $TIMESTAMP"
echo ""
check_gateway
check_resources
check_error_logs
check_configs
check_learning
generate_report
echo ""
echo "✅ 检测完成"
}
main "$@"
+222
View File
@@ -0,0 +1,222 @@
#!/bin/bash
# 代理域名管理器
# 功能:检查域名是否需要代理,自动添加到列表
# 用法:
# ./proxy-domain-check.sh check <域名> - 检查域名是否需要代理
# ./proxy-domain-check.sh add <域名> - 手动添加域名到列表
# ./proxy-domain-check.sh list - 显示当前列表
# ./proxy-domain-check.sh test <域名> - 测试域名直连和代理访问
PROXY_MANAGER_DIR="/root/.openclaw/scripts/proxy-manager"
DOMAIN_LIST="${PROXY_MANAGER_DIR}/proxy-domains.txt"
LOG_FILE="${PROXY_MANAGER_DIR}/access.log"
PROXY_URL="http://192.168.0.66:7890" # 代理地址
TIMEOUT=5
mkdir -p "$PROXY_MANAGER_DIR"
touch "$DOMAIN_LIST"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# 提取域名(去除协议和路径)
extract_domain() {
local url="$1"
# 去除 http:// https://
url="${url#http://}"
url="${url#https://}"
# 去除路径
url="${url%%/*}"
# 去除端口
url="${url%%:*}"
echo "$url"
}
# 检查域名是否在列表中
is_proxy_required() {
local domain="$1"
local base_domain=$(echo "$domain" | sed 's/^www\.//')
# 检查完整域名和各级父域名
while [ -n "$base_domain" ]; do
# 直接匹配
if grep -q "^${base_domain}$" "$DOMAIN_LIST" 2>/dev/null; then
return 0
fi
# 通配符匹配
if grep -q "^\*\.$base_domain$" "$DOMAIN_LIST" 2>/dev/null; then
return 0
fi
# 父域名(去掉一级)
base_domain="${base_domain#*.}"
done
return 1
}
# 测试直连是否可用
test_direct() {
local domain="$1"
local result
# 尝试使用 curl 直连
result=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout "$TIMEOUT" \
--resolve "${domain}:443:8.8.8.8" \
"https://${domain}" 2>/dev/null || echo "FAILED")
if [ "$result" = "200" ] || [ "$result" = "301" ] || [ "$result" = "302" ]; then
return 0 # 直连成功
fi
# 尝试 HTTP
result=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout "$TIMEOUT" \
--resolve "${domain}:80:8.8.8.8" \
"http://${domain}" 2>/dev/null || echo "FAILED")
if [ "$result" = "200" ] || [ "$result" = "301" ] || [ "$result" = "302" ]; then
return 0
fi
return 1 # 直连失败
}
# 测试代理是否可用
test_proxy() {
local domain="$1"
local result
result=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout "$TIMEOUT" \
--proxy "$PROXY_URL" \
"https://${domain}" 2>/dev/null || echo "FAILED")
if [ "$result" = "200" ] || [ "$result" = "301" ] || [ "$result" = "302" ]; then
return 0 # 代理成功
fi
return 1 # 代理失败
}
# 检查并自动添加域名
check_and_add() {
local domain="$1"
local action="$2" # auto 或 manual
if is_proxy_required "$domain"; then
echo "⛔ 域名 '$domain' 已在代理列表中"
log "SKIP: $domain - already in list"
return 1
fi
echo "🔍 检测域名: $domain"
log "CHECK: $domain"
# 测试直连
if test_direct "$domain"; then
echo "✅ 直连可用,无需代理"
log "OK: $domain - direct access works"
return 0
fi
# 测试代理
if test_proxy "$domain"; then
echo "🌐 直连失败,代理可用,添加到列表"
log "ADD: $domain - proxy required"
# 添加到列表
echo "$domain" >> "$DOMAIN_LIST"
echo "✅ 已添加 '$domain' 到代理列表"
# 发送 Telegram 通知(如果配置)
if [ -f "${PROXY_MANAGER_DIR}/../send-session-alert.sh" ]; then
bash "${PROXY_MANAGER_DIR}/../send-session-alert.sh" "proxy" "$domain" "代理访问已添加"
fi
return 0
fi
echo "❌ 直连和代理都无法访问"
log "FAIL: $domain - neither direct nor proxy works"
return 1
}
# 手动添加域名
add_domain() {
local domain="$1"
# 提取纯域名
domain=$(extract_domain "$domain")
if is_proxy_required "$domain"; then
echo "⛔ '$domain' 已在代理列表中"
return 1
fi
echo "$domain" >> "$DOMAIN_LIST"
echo "✅ 已添加 '$domain' 到代理列表"
log "MANUAL_ADD: $domain"
}
# 显示列表
show_list() {
echo "📋 代理域名列表 (共 $(grep -c '^[^#]' "$DOMAIN_LIST") 个):"
echo "----------------------------------------"
grep -v '^#' "$DOMAIN_LIST" | grep -v '^$' | sort
echo "----------------------------------------"
}
# 主命令处理
case "$1" in
check)
if [ -z "$2" ]; then
echo "用法: $0 check <域名>"
exit 1
fi
domain=$(extract_domain "$2")
check_and_add "$domain" auto
;;
add)
if [ -z "$2" ]; then
echo "用法: $0 add <域名>"
exit 1
fi
add_domain "$2"
;;
list)
show_list
;;
test)
if [ -z "$2" ]; then
echo "用法: $0 test <域名>"
exit 1
fi
domain=$(extract_domain "$2")
echo "🌐 测试域名: $domain"
echo ""
echo "直连测试:"
if test_direct "$domain"; then
echo " ✅ 成功"
else
echo " ❌ 失败"
fi
echo ""
echo "代理测试:"
if test_proxy "$domain"; then
echo " ✅ 成功"
else
echo " ❌ 失败"
fi
;;
*)
echo "代理域名管理器 v1.0"
echo ""
echo "用法: $0 <命令> [参数]"
echo ""
echo "命令:"
echo " check <域名> - 检查域名,自动添加到列表(如需要)"
echo " add <域名> - 手动添加域名到列表"
echo " list - 显示当前代理域名列表"
echo " test <域名> - 测试直连和代理访问"
echo ""
echo "示例:"
echo " $0 check google.com"
echo " $0 add twitter.com"
echo " $0 list"
echo " $0 test youtube.com"
;;
esac
+54
View File
@@ -0,0 +1,54 @@
#!/bin/bash
# 资源守卫 - 执行前检查机器资源
THRESHOLD_MEM=80
THRESHOLD_LOAD=1.5
MIN_DISK_GB=5
MIN_MEM_AVAILABLE_GB=1
LOG_DIR="/var/log/openclaw"
RESOURCE_LOG="${LOG_DIR}/resource-guard.log"
check_resources() {
local cpu_usage load_5min num_cores normalized_load mem_total mem_available mem_pct disk_free exit_code=0
load_5min=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $2}' | sed 's/,//')
num_cores=$(nproc)
normalized_load=$(echo "scale=2; $load_5min / $num_cores" | bc 2>/dev/null || echo "99")
# 可靠提取Mem行
local mem_info
mem_info=$(free -m | awk 'NR==2{print $2, $3, $4, $7}')
mem_total=$(echo "$mem_info" | awk '{print $1}')
mem_available=$(echo "$mem_info" | awk '{print $4}')
mem_pct=$(( (mem_total - mem_available) * 100 / mem_total ))
disk_free=$(df -BG / | tail -1 | awk '{print $4}' | tr -d 'G')
echo "[资源] 负载:${load_5min}(归一化:${normalized_load}) 内存:${mem_pct}% 可用:${mem_available}MB 磁盘:${disk_free}GB"
(( $(echo "$normalized_load > $THRESHOLD_LOAD" | bc -l 2>/dev/null) )) && echo "⚠️ 负载(${load_5min})>阈值(${THRESHOLD_LOAD}x$num_cores核)" && exit_code=1
[ "$mem_pct" -gt "$THRESHOLD_MEM" ] && echo "⚠️ 内存(${mem_pct}%)>${THRESHOLD_MEM}%" && exit_code=1
[ "$mem_available" -lt $((MIN_MEM_AVAILABLE_GB * 1024)) ] && echo "⚠️ 可用内存(${mem_available}MB)<${MIN_MEM_AVAILABLE_GB}GB" && exit_code=1
[ "$disk_free" -lt "$MIN_DISK_GB" ] && echo "⚠️ 磁盘(${disk_free}GB)<${MIN_DISK_GB}GB" && exit_code=1
[ "$exit_code" -eq 0 ] && echo "✅ 资源检查通过" || echo "❌ 资源不足"
# 写入日志(无论通过与否)
mkdir -p "$LOG_DIR"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] load=${load_5min}(norm=${normalized_load}) mem=${mem_pct}% avail=${mem_available}MB disk=${disk_free}GB -> $([ $exit_code -eq 0 ] && echo PASS || echo FAIL)" >> "$RESOURCE_LOG"
return $exit_code
}
case "$1" in
--check) check_resources ;;
*)
if check_resources; then
eval "$*"
else
echo "跳过: $*"
exit 1
fi
;;
esac
+80
View File
@@ -0,0 +1,80 @@
#!/bin/bash
# ============================================================================
# 定时后台学习 - crontab 管理
# ============================================================================
# 添加定时任务
add_cron() {
echo "添加定时学习任务..."
# 青龙:每小时学习1轮
(crontab -l 2>/dev/null | grep -v "qinglong-auto-learning"; echo "0 * * * * /root/.openclaw/scripts/auto-learning.sh 1 >> /var/log/openclaw/sleep-learning/qinglong-cron.log 2>&1") | crontab -
# 守护者:每2小时学习1轮
(crontab -l 2>/dev/null | grep -v "guardian-auto-learning"; echo "0 */2 * * * /root/.openclaw/scripts/auto-learning.sh 1 >> /var/log/openclaw/sleep-learning/guardian-cron.log 2>&1") | crontab -
echo "✅ 定时任务已添加"
}
# 移除定时任务
remove_cron() {
echo "移除定时学习任务..."
crontab -l 2>/dev/null | grep -v "auto-learning" | crontab -
echo "✅ 已移除"
}
# 立即触发学习(不等待cron)
trigger_now() {
local robot="${1:-all}"
if [ "$robot" = "qinglong" ] || [ "$robot" = "all" ]; then
echo "🚀 立即触发青龙学习..."
nohup /root/.openclaw/scripts/auto-learning.sh 1 > /tmp/qinglong-trigger.log 2>&1 &
echo "青龙 PID: $!"
fi
if [ "$robot" = "guardian" ] || [ "$robot" = "all" ]; then
echo "🚀 立即触发守护者学习..."
nohup /root/.openclaw/scripts/auto-learning.sh 1 > /tmp/guardian-trigger.log 2>&1 &
echo "守护者 PID: $!"
fi
}
# 查看cron状态
status() {
echo "╔════════════════════════════════════════════════════╗"
echo "║ 定时学习任务状态 ║"
echo "╚════════════════════════════════════════════════════╝"
echo ""
echo "📋 当前 Cron 任务:"
crontab -l 2>/dev/null | grep "auto-learning" || echo " 无定时任务"
echo ""
echo "🔄 运行中的学习进程:"
ps aux | grep "auto-learning.sh" | grep -v grep || echo " 无运行中的进程"
echo ""
echo "📊 最近学习记录:"
echo "青龙: $(tail -3 /var/log/openclaw/sleep-learning/qinglong-cron.log 2>/dev/null | head -1 || echo '无')"
echo "守护者: $(tail -3 /var/log/openclaw/sleep-learning/guardian-cron.log 2>/dev/null | head -1 || echo '无')"
}
# 主程序
case "$1" in
add)
add_cron
;;
remove)
remove_cron
;;
trigger)
trigger_now "${2:-all}"
;;
status)
status
;;
*)
echo "用法: $0 {add|remove|trigger [qinglong|guardian]|status}"
;;
esac
+50
View File
@@ -0,0 +1,50 @@
#!/bin/bash
# 发送会话提醒到 Telegram
# 用法: ./send-session-alert.sh <类型> <会话ID> <大小MB>
# 类型: warn, new
TYPE="$1"
SESSION_ID="$2"
SIZE_MB="$3"
if [ -z "$TYPE" ] || [ -z "$SESSION_ID" ] || [ -z "$SIZE_MB" ]; then
echo "用法: $0 <warn|new> <会话ID> <大小MB>"
exit 1
fi
MESSAGE_FILE="/tmp/openclaw-temp-message.json"
case "$TYPE" in
warn)
cat > "$MESSAGE_FILE" << EOF
{
"action": "send",
"target": "5117446326",
"message": "⚠️ 会话文件过大提醒\n\n会话: ${SESSION_ID}\n大小: ${SIZE_MB}MB\n\n建议开启新对话以避免性能问题。",
"channel": "telegram"
}
EOF
;;
new)
cat > "$MESSAGE_FILE" << EOF
{
"action": "send",
"target": "5117446326",
"message": "🆕 已自动开启新会话\n\n旧会话: ${SESSION_ID}\n大小: ${SIZE_MB}MB\n\n新对话已就绪。",
"channel": "telegram"
}
EOF
;;
*)
echo "未知类型: $TYPE"
exit 1
;;
esac
# 发送到 OpenClaw Gateway
curl -s -X POST "http://127.0.0.1:18789/messages" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer openclaw-guardian-token-2nd" \
-d @"$MESSAGE_FILE"
rm -f "$MESSAGE_FILE"
+219
View File
@@ -0,0 +1,219 @@
#!/bin/bash
# ============================================================================
# SEO 检查脚本 - 检查文章中的链接和SEO问题
# ============================================================================
# 配置
WORKSPACE="/root/.openclaw/workspace"
HQBSH_DIR="${WORKSPACE}/hqbsh"
SEO_LOG="/var/log/openclaw/seo-check.log"
mkdir -p "$(dirname "$SEO_LOG")"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$SEO_LOG"
}
# ============================================================================
# 检查问题链接
# ============================================================================
check_broken_links() {
local file="$1"
local issues=()
# 1. 检查伪链接格式 [标题]()
while IFS= read -r line; do
if echo "$line" | grep -qE '\[.+\]\(\s*\)'; then
issues+=("空括号链接: $line")
fi
done < "$file"
# 2. 检查锚点伪链接 [标题](#)
while IFS= read -r line; do
if echo "$line" | grep -qE '\[.+\]\(#\)'; then
issues+=("空锚点链接: $line")
fi
done < "$file"
# 3. 检查纯文本"原贴"字样但无链接
if grep -qE '原贴.*:$' "$file"; then
issues+=("原贴后面没有链接")
fi
# 4. 检查链接格式不完整 [标题](链接不完整
if grep -qE '\]\([^\)]+$' "$file"; then
issues+=("未闭合的链接括号")
fi
printf '%s\n' "${issues[@]}"
}
# ============================================================================
# 检查SEO元素
# ============================================================================
check_seo_elements() {
local file="$1"
local issues=()
# 检查是否缺少 H1/H2 标题
if ! grep -qE '^# ' "$file"; then
issues+=("缺少 H1 标题 (# 标题)")
fi
# 检查图片是否缺少 alt 文本
while IFS= read -r line; do
if echo "$line" | grep -qE '!\[\]\('; then
issues+=("图片缺少 alt 文本: $line")
fi
done < "$file"
# 检查段落是否太长(超过300字)
local content=$(cat "$file" | sed 's/```.*//g' | sed 's/```//g')
local paragraphs=$(echo "$content" | awk '/^[^#*>]/ {if(length > 200) print NR": "$0}' | head -5)
if [ -n "$paragraphs" ]; then
issues+=("长段落可能影响阅读性")
fi
printf '%s\n' "${issues[@]}"
}
# ============================================================================
# 生成SEO优化建议
# ============================================================================
generate_seo_suggestions() {
local file="$1"
local suggestions=()
# 建议1: 外部链接应该添加真实URL
if grep -qE '\[.+\]\(\s*\)' "$file"; then
suggestions+=("需要修复空链接")
fi
# 建议2: 内部链接应该添加锚点ID
if grep -qE '\[.+\]\(#.*\)' "$file"; then
suggestions+=("内部锚点链接格式正确 ✓")
else
if grep -qE '^## ' "$file"; then
suggestions+=("建议添加目录和锚点链接")
fi
fi
# 建议3: 元数据
if ! grep -qE '^> ' "$file"; then
suggestions+=("建议添加作者/时间等元数据")
fi
printf '%s\n' "${suggestions[@]}"
}
# ============================================================================
# 修复问题链接
# ============================================================================
fix_links() {
local file="$1"
local fixed=0
# 修复空括号链接 [标题]()
if grep -qE '\[.+\]\(\s*\)' "$file"; then
echo "发现空链接,正在修复..."
# 将 [标题]() 转换为 [标题](真实链接占位)
sed -i 's/\]\(\s*\)/](请添加真实链接)/g' "$file"
fixed=$((fixed + 1))
fi
# 修复原贴链接
if grep -qE '原贴.*:$' "$file"; then
echo "发现原贴占位符,正在修复..."
sed -i 's/原贴.*:$/原贴链接: 请添加真实URL/g' "$file"
fixed=$((fixed + 1))
fi
if [ $fixed -gt 0 ]; then
echo "✅ 已修复 $fixed 个问题"
return 0
else
echo "✅ 未发现问题链接"
return 1
fi
}
# ============================================================================
# 主程序 - 检查最近文章
# ============================================================================
check_recent_articles() {
local count=${1:-5}
echo "╔════════════════════════════════════════════════════╗"
echo "║ SEO 检查 - 最近 $count 篇文章 ║"
echo "╚════════════════════════════════════════════════════╝"
echo ""
# 查找最近修改的markdown文件
local files=$(find "${HQBSH_DIR}" -name "*.md" -mmin -180 2>/dev/null | head "$count")
if [ -z "$files" ]; then
echo "⚠️ 最近没有找到hqbsh文章"
echo ""
echo "检查 workspace 下的其他文章:"
files=$(find "${WORKSPACE}" -name "*.md" -mmin -180 2>/dev/null | grep -v sleep-learning | head "$count")
fi
local total_issues=0
for file in $files; do
local filename=$(basename "$file")
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📄 检查: $filename"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# 检查问题链接
local issues=$(check_broken_links "$file")
if [ -n "$issues" ]; then
echo "❌ 问题链接:"
echo "$issues" | head -5
total_issues=$((total_issues + $(echo "$issues" | wc -l)))
else
echo "✅ 链接检查:正常"
fi
# 检查SEO元素
local seo_issues=$(check_seo_elements "$file")
if [ -n "$seo_issues" ]; then
echo "⚠️ SEO建议:"
echo "$seo_issues" | head -3
fi
# 生成优化建议
local suggestions=$(generate_seo_suggestions "$file")
if [ -n "$suggestions" ]; then
echo ""
echo "💡 优化建议:"
echo "$suggestions"
fi
echo ""
done
echo "╔════════════════════════════════════════════════════╗"
echo "║ 共发现 $total_issues 个问题 ║"
echo "╚════════════════════════════════════════════════════╝"
}
# ============================================================================
# 主程序
# ============================================================================
case "$1" in
check)
check_recent_articles "${2:-5}"
;;
fix)
fix_links "$2"
;;
*)
echo "用法: $0 {check [数量]|fix <文件>}"
echo ""
echo "示例:"
echo " $0 check 10 # 检查最近10篇文章"
echo " $0 fix file.md # 修复指定文件的链接问题"
;;
esac
+62
View File
@@ -0,0 +1,62 @@
#!/bin/bash
# SEO进化知识吸收 v1.0
# 发现项目 → 分析 → 提取知识 → 优化自己的系统
CANDIDATES="/root/.openclaw/workspace/seo/evolution-candidates.md"
KNOWLEDGE="/root/.openclaw/workspace/seo/knowledge-absorbed.md"
LOG="/root/.openclaw/logs/evolution-absorb.log"
log() { echo "[$(date '%H:%M:%S')] $1" | tee -a "$LOG"; }
# 分析项目并提取知识
analyze_project() {
local url="$1"
local name="$2"
local proxy="http://192.168.0.31:7890"
local token="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"
log "分析: $name"
# 获取项目详情(带认证)
local content=$(curl -s --proxy "$proxy" --max-time 20 \
-H "Authorization: token $token" \
"https://api.github.com/repos/$name" 2>/dev/null)
[ -z "$content" ] && return
# 提取有用信息
local stars=$(echo "$content" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('stargazers_count','0')" 2>/dev/null || echo "0")
local desc=$(echo "$content" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('description','')" 2>/dev/null || echo "")
local lang=$(echo "$content" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('language','')" 2>/dev/null || echo "")
log "⭐$stars $name ($lang)"
log " $desc"
# 提取技术要点
case "$desc" in
*SEO*)
log " → SEO相关知识"
echo "## SEO知识: $name" >> "$KNOWLEDGE"
echo "⭐$stars $desc" >> "$KNOWLEDGE"
echo "链接: https://github.com/$name" >> "$KNOWLEDGE"
echo "" >> "$KNOWLEDGE"
;;
*keyword*|*crawl*|*scrap*)
log " → 爬虫技术"
echo "## 爬虫技术: $name" >> "$KNOWLEDGE"
echo "⭐$stars $desc" >> "$KNOWLEDGE"
echo "" >> "$KNOWLEDGE"
;;
esac
}
# 主流程
log "=== 知识吸收开始 ==="
# 读取候选项目并分析
if [ -f "$CANDIDATES" ]; then
while IFS= read -r line; do
[[ "$line" =~ github.com/([^/]+/[^\s]+) ]] && analyze_project "${BASH_REMATCH[1]}" "${BASH_REMATCH[1]}"
done < "$CANDIDATES"
fi
log "=== 知识吸收完成 ==="
@@ -0,0 +1,134 @@
#!/bin/bash
# SEO进化猎手完整流程 v1.0
# 扫描 → 评估 → 安装 → 沉淀
PROGRESS_FILE="/root/.openclaw/workspace/seo/evolution-hunter-progress.md"
CANDIDATES="/root/.openclaw/workspace/seo/evolution-candidates.txt"
EVAL_LOG="/root/.openclaw/workspace/seo/evolution-log.md"
LOG_FILE="/root/.openclaw/logs/seo-evolution.log"
PROXY="http://192.168.0.66:7890"
TIMEOUT=20
log() { echo "[$(date '+%H:%M:%S') $1" | tee -a "$LOG_FILE" 2>/dev/null; }
# 资源检查
check_resource() {
bash /root/.openclaw/scripts/resource-guard.sh > /dev/null 2>&1
}
# GitHub搜索
github_search() {
local query="$1"
local url="https://api.github.com/search/repositories?q=$(echo "$query" | python3 -c "import urllib.parse,sys; print(urllib.parse.quote(sys.stdin.read().strip()))&sort=stars&order=desc&per_page=10"
curl -s --max-time $TIMEOUT --proxy "$PROXY" \
-H "Accept: application/vnd.github.v3+json" \
-H "User-Agent: Mozilla/5.0" "$url" 2>/dev/null | python3 -c "
import json,sys
try:
data=json.load(sys.stdin)
for item in data.get('items',[])[:5]:
stars=item.get('stargazers_count',0)
lang=item.get('language','N/A') or 'N/A'
desc=str(item.get('description','N/A'))[:80]
url=item.get('html_url','N/A')
name=item.get('full_name','')
print(f'NAME:{name}')
print(f'STARS:{stars}')
print(f'DESC:{desc}')
print(f'LANG:{lang}')
print(f'URL:{url}')
print('---')
except: pass
" 2>/dev/null
}
# 评估项目
evaluate_project() {
local name="$1"
local stars="$2"
local desc="$3"
local url="$4"
# 高价值关键词
case "$desc $name" in
*seo*|*search*|*keyword*|*ranking*)
echo "SEO直接相关"
return 2
;;
*scraper*|*crawler*|*browser*|*automation*)
echo "自动化工具"
return 2
;;
*playwright*|*selenium*|*puppeteer*)
echo "浏览器自动化"
return 2
;;
*agent*|*tool*|*cli*|*api*)
echo "Agent/工具"
return 1
;;
*)
return 0
;;
esac
}
# 主流程
main() {
log "========== SEO进化猎手启动 =========="
check_resource || { log "资源不足"; exit 0; }
mkdir -p "$(dirname "$CANDIDATES")"
> "$CANDIDATES"
# 扫描
log "扫描SEO相关项目..."
for query in "SEO tool python" "web scraper python" "keyword research" "content generator python"; do
github_search "$query" >> "$EVAL_LOG"
done
# 提取候选
log "评估候选项目..."
while IFS=: read -r field value; do
case $field in
NAME*) name="$value" ;;
STARS*) stars="$value" ;;
DESC*) desc="$value" ;;
URL*) url="$value" ;;
---)
if [ -n "$name" ]; then
result=$(evaluate_project "$name" "$stars" "$desc" "$url")
priority=$?
if [ $priority -ge 1 ]; then
echo "【$result】⭐$stars $name" >> "$CANDIDATES"
echo " $desc" >> "$CANDIDATES"
echo " $url" >> "$CANDIDATES"
echo "" >> "$CANDIDATES"
fi
fi
name=""
;;
esac
done < "$EVAL_LOG"
# 统计
count=$(wc -l < "$CANDIDATES" 2>/dev/null || echo 0)
log "发现 $count 个候选"
# 自动安装高优先级
log "处理候选安装..."
while IFS= read -r line; do
echo "$line"
done < "$CANDIDATES"
# 记录
echo "## $(date '+%Y-%m-%d %H:%M'" >> "$PROGRESS_FILE"
echo "" >> "$PROGRESS_FILE"
cat "$CANDIDATES" >> "$PROGRESS_FILE"
echo "" >> "$PROGRESS_FILE"
log "========== 进化猎手完成 =========="
}
main
+50
View File
@@ -0,0 +1,50 @@
#!/bin/bash
# SEO进化自动安装 v1.0
# 发现高价值项目 → 自动安装 → 知识沉淀
CANDIDATES="/root/.openclaw/workspace/seo/evolution-candidates.md"
LOG="/root/.openclaw/logs/evolution-install.log"
log() { echo "[$(date '+%H:%M:%S') $1"; }
# 自动安装Python包
install_pip() {
local repo="$1"
log "尝试pip安装: $repo"
pip install --break-system-packages "git+https://github.com/$repo" 2>/dev/null && log "✅ 安装成功" || log "❌ 安装失败"
}
# 克隆技能仓库
install_skill() {
local repo="$1"
local skill_dir="/root/.openclaw/skills"
log "克隆技能: $repo"
git clone "https://github.com/$repo" "$skill_dir/$(basename "$repo") 2>/dev/null && log "✅ 克隆成功" || log "❌ 克隆失败"
}
# 主流程
main() {
log "=== 进化自动安装 ==="
[ -f "$CANDIDATES" ] || { log "无候选文件"; exit 0; }
while IFS= read -r line; do
case "$line" in
*SEO*|*seo*)
log "SEO相关: $line"
# 提取GitHub项目名
if [[ "$line" =~ github.com/([^/]+/[^/]+) ]]; ${BASH_REMATCH[1]} && install_pip "${BASH_REMATCH[1]}"
;;
*browser*|*automation*)
log "自动化工具: $line"
;;
*)
log "其他: $line"
;;
esac
done < "$CANDIDATES"
log "=== 安装完成 ==="
}
main
+37
View File
@@ -0,0 +1,37 @@
#!/bin/bash
# SEO进化猎手报告生成器 v2.0 - 调用 Python 版深度分析
# 资源检查
RESOURCE_CHECK="/root/.openclaw/scripts/resource-guard.sh"
if [ -f "$RESOURCE_CHECK" ]; then
if ! bash "$RESOURCE_CHECK" > /dev/null 2>&1; then
echo "[SKIP] 资源不足,跳过本次执行"
exit 0
fi
fi
LOG_FILE="/root/.openclaw/workspace/seo/logs/seo-evolution.log"
log() { echo "[$(date '+%H:%M:%S')] $1" | tee -a "$LOG_FILE" 2>/dev/null; }
main() {
log "========== SEO进化猎手 v2.0 开始 =========="
cd /root/.openclaw/workspace/seo
# 1. 运行深度分析猎手
log "阶段1: 深度分析 GitHub 项目..."
python3 seo_evolution_hunter.py >> "$LOG_FILE" 2>&1
# 2. 运行评估器
log "阶段2: 评估项目价值..."
python3 evolution_evaluator.py >> "$LOG_FILE" 2>&1
# 3. 主动进化执行
log "阶段3: 自动进化(无需确认)..."
python3 evolution_executor.py >> "$LOG_FILE" 2>&1
log "========== SEO进化猎手 v2.0 完成 =========="
}
main "$@"
+89
View File
@@ -0,0 +1,89 @@
#!/bin/bash
# SEO进化猎手 v1.0 - 扫描SEO新工具/技术/策略
# 自动发现GitHub热门SEO工具和最新技术
PROGRESS_FILE="/root/.openclaw/workspace/seo/evolution-hunter-progress.md"
OUTPUT_FILE="/root/.openclaw/workspace/seo/logs/seo-evolution-scan.md"
PROXY="http://192.168.0.66:7890"
LOG_FILE="/root/.openclaw/workspace/seo/logs/seo-evolution.log"
TIMEOUT=20
log() { echo "[$(date '+%H:%M:%S')] $1" | tee -a "$LOG_FILE" 2>/dev/null; }
# 获取已扫描关键词
get_scanned() {
grep -E "^## 第.*扫描" "$PROGRESS_FILE" 2>/dev/null | \
sed -E 's/^## 第[0-9]+轮://' | \
tr '[:upper:]' '[:lower:]' | sort -u
}
# GitHub搜索
github_search() {
local query="$1"
local url="https://api.github.com/search/repositories?q=$(echo "$query" | python3 -c "import urllib.parse,sys; print(urllib.parse.quote(sys.stdin.read().strip()))")&sort=stars&order=desc&per_page=5"
log "搜索: ${query:0:50}"
curl -s --max-time $TIMEOUT \
--proxy "$PROXY" \
-H "Accept: application/vnd.github.v3+json" \
-H "User-Agent: Mozilla/5.0" "$url" 2>/dev/null | python3 -c "
import json,sys
try:
data = json.load(sys.stdin)
for item in data.get('items', [])[:5]:
stars = item.get('stargazers_count', 0)
lang = item.get('language', 'N/A') or 'N/A'
desc = str(item.get('description', 'N/A'))[:100]
url = item.get('html_url', 'N/A')
print(f'| {item[\"full_name\"]} | ⭐{stars} | {lang} | {desc} | {url} |')
except: pass
" 2>/dev/null
}
main() {
log "========== SEO进化猎手启动 =========="
mkdir -p "$(dirname "$OUTPUT_FILE")"
# 记录轮次
round=$(grep -c "^## 第" "$PROGRESS_FILE" 2>/dev/null || echo 0)
round=$((round + 1))
{
echo "## 第${round}轮:$(date '+%Y-%m-%d %H:%M')"
echo ""
echo "### 已扫描关键词: $(get_scanned | tr '\n' ', ')"
echo ""
echo "### 发现结果"
echo ""
echo "#### SEO工具"
echo "| 项目 | Stars | 语言 | 简介 |"
echo "|-----|------|------|------|"
github_search "SEO tool python automation" || true
github_search "web scraper SEO python" || true
echo ""
echo "#### 内容生成"
echo "| 项目 | Stars | 语言 | 简介 |"
echo "|-----|------|------|------|"
github_search "AI content generator open source" || true
github_search "article writer python" || true
echo ""
echo "#### 关键词研究"
echo "| 项目 | Stars | 语言 | 简介 |"
echo "|-----|------|------|------|"
github_search "keyword research API python" || true
github_search "SEO analysis tool" || true
echo ""
echo "*扫描完成: $(date '+%H:%M:%S')*"
} > "$OUTPUT_FILE"
log "输出文件已创建: $(wc -c < "$OUTPUT_FILE")bytes"
log "========== SEO进化猎手结束 =========="
}
main "$@"
@@ -0,0 +1,75 @@
#!/bin/bash
# 守护者健康检查 v1.0 - SEO系统专用
# 基于4号机health-check-standardized.sh简化
LOG_DIR="/root/.openclaw/logs/health"
mkdir -p "$LOG_DIR"
LOG_FILE="$LOG_DIR/health-$(date '+%Y%m%d').log"
log() { echo "[$(date '+%H:%M:%S')] $1" | tee -a "$LOG_FILE"; }
section() { echo ""; echo "=== $1 ==="; echo "=== $1 ===" >> "$LOG_FILE"; }
# 检查函数
check_gateway() {
section "Gateway"
if pgrep -f "openclaw.*gateway" > /dev/null 2>&1; then
local pid=$(pgrep -f "openclaw.*gateway" | head -1)
log "✅ Gateway运行中 (PID: $pid)"
else
log "❌ Gateway未运行"
fi
# 端口检查
if curl -s --noproxy 127.0.0.1 --max-time 5 http://127.0.0.1:18789 > /dev/null 2>&1; then
log "✅ 端口18789响应正常"
else
log "❌ 端口18789无响应"
fi
}
check_seo_tasks() {
section "SEO定时任务"
# 检查seo发布
if pgrep -f "seo.*publish\|seo.*monetizer" > /dev/null 2>&1; then
log "✅ SEO任务运行中"
else
log "ℹ️ SEO任务未运行(可能在等待)"
fi
# 检查crontab
local cron_count=$(crontab -l 2>/dev/null | grep -c "seo\|SEO" || echo "0")
log "ℹ️ SEO相关cron: ${cron_count}个"
}
check_resources() {
section "资源状态"
local cpu=$(top -bn1 2>/dev/null | awk 'NR==2 {print $2}' | sed 's/%Cpu(s)//')
local mem=$(free -h | awk 'NR==2 {print $3}')
local disk=$(df -h / | tail -1 | awk '{print $5}')
log "ℹ️ CPU: ${cpu}%"
log "ℹ️ 内存: ${mem}"
log "ℹ️ 磁盘: ${disk}"
}
check_openbjb() {
section "openbjb.com站点"
if curl -s --noproxy '*' --max-time 10 "https://openbjb.com" > /dev/null 2>&1; then
log "✅ openbjb.com 可访问"
else
log "❌ openbjb.com 连接失败"
fi
}
main() {
log "========== 守护者健康检查 =========="
check_gateway
check_seo_tasks
check_resources
check_openbjb
log "========== 健康检查完成 =========="
}
main
+82
View File
@@ -0,0 +1,82 @@
#!/bin/bash
# 会话隔离管理器
# 功能: 自动归档和清理旧会话,防止会话文件冲突
# 策略: 文件超过2小时未更新 = 已完成 = 归档
SESSION_DIR="/root/.openclaw/agents/main/sessions"
ARCHIVE_DIR="/root/.openclaw/agents/main/sessions-archive"
MAX_SESSION_AGE_HOURS=2
echo "=== 会话隔离管理 $(date) ==="
# 创建归档目录
mkdir -p "$ARCHIVE_DIR"
# 1. 归档超过2小时未更新的会话
echo "1. 归档超过${MAX_SESSION_AGE_HOURS}小时未更新的会话..."
current_time=$(date +%s)
archived_count=0
# 获取会话文件列表
session_files=($SESSION_DIR/*.jsonl)
for session in "${session_files[@]}"; do
[ -f "$session" ] || continue
# 获取文件名
filename=$(basename "$session")
# 跳过主会话 (agent:main)
if [[ "$filename" == *"18095fa2"* ]]; then
continue
fi
# 获取文件修改时间
mtime=$(stat -c %Y "$session" 2>/dev/null)
[ -z "$mtime" ] && continue
# 计算时间差(小时)
age_hours=$(( (current_time - mtime) / 3600 ))
# 超过2小时未更新,归档
if [ "$age_hours" -ge "$MAX_SESSION_AGE_HOURS" ]; then
mv "$session" "$ARCHIVE_DIR/" 2>/dev/null
echo " 归档: $filename (${age_hours}h未更新)"
((archived_count++))
fi
done
echo " 已归档 $archived_count 个会话"
# 2. 清理归档目录中超过3天的会话
echo ""
echo "2. 清理归档目录中超过3天的会话..."
find "$ARCHIVE_DIR" -name "*.jsonl" -type f -mtime +3 -delete 2>/dev/null
find "$ARCHIVE_DIR" -name "*.jsonl.gz" -type f -mtime +3 -delete 2>/dev/null
# 3. 压缩超大会话文件 (>10MB)
echo ""
echo "3. 压缩超大会话..."
for session in "$SESSION_DIR"/*.jsonl; do
[ -f "$session" ] || continue
size_mb=$(du -m "$session" 2>/dev/null | cut -f1)
if [ "$size_mb" -gt 10 ] 2>/dev/null; then
gzip -k "$session" 2>/dev/null
echo " 已压缩: $(basename "$session") (${size_mb}MB)"
fi
done
# 4. 清理锁文件
echo ""
echo "4. 清理过期锁文件..."
find "$SESSION_DIR" -name "*.lock" -type f -mmin +60 -delete 2>/dev/null
# 5. 统计
echo ""
echo "=== 当前状态 ==="
echo "活跃会话: $(ls $SESSION_DIR/*.jsonl 2>/dev/null | wc -l)"
echo "归档会话: $(ls $ARCHIVE_DIR/*.jsonl 2>/dev/null | wc -l)"
echo "归档压缩: $(ls $ARCHIVE_DIR/*.jsonl.gz 2>/dev/null | wc -l)"
echo ""
echo "完成!"
+32
View File
@@ -0,0 +1,32 @@
#!/bin/bash
SESSIONS_DIR="/root/.openclaw/agents/main/sessions"
ALERT_THRESHOLD_MB=8
AUTO_THRESHOLD_MB=5
LOG_DIR="/var/log/openclaw-monitor"
ALERT_LOG="${LOG_DIR}/alerts.log"
mkdir -p "$LOG_DIR"
auto_start_new_session() {
local file="$1" size_mb="$2"
echo "[AUTO] $(date '+%Y-%m-%d %H:%M:%S') SESSION TOO LARGE: $file (${size_mb}MB > ${AUTO_THRESHOLD_MB}MB) - Auto-starting new session" >> "$ALERT_LOG"
local basename=$(basename "$file")
cp "$file" "${SESSIONS_DIR}/${basename%.jsonl}_archived_$(date +%Y%m%d_%H%M%S).jsonl"
echo "[]" > "$file"
NO_PROXY="localhost,127.0.0.1,192.168.0.66" openclaw gateway restart
}
while true; do
for file in "$SESSIONS_DIR"/*.jsonl; do
if [ -f "$file" ]; then
size_kb=$(stat -c%s "$file" 2>/dev/null || echo 0)
size_mb=$(awk "BEGIN {printf \"%.2f\", $size_kb/1024}")
if [ "$size_kb" -gt $((ALERT_THRESHOLD_MB * 1024)) ]; then
echo "[ALERT] $(date '+%Y-%m-%d %H:%M:%S') SESSION TOO LARGE: $file (${size_mb}MB)" >> "$ALERT_LOG"
fi
if [ "$size_kb" -gt $((AUTO_THRESHOLD_MB * 1024)) ]; then
auto_start_new_session "$file" "$size_mb"
fi
fi
done
sleep 300
done
+21
View File
@@ -0,0 +1,21 @@
#!/bin/bash
ACTION="$1"; DOMAIN="$2"; shift 2 || true; CONTENT="$*"
EXPERIENCE_DIR="/root/.openclaw/memory/06-site-experience"
mkdir -p "$EXPERIENCE_DIR"
case "$ACTION" in
add)
SAFE_DOMAIN=$(echo "$DOMAIN" | sed 's/[^a-zA-Z0-9.-]/_/g')
FILE="$EXPERIENCE_DIR/${SAFE_DOMAIN}.md"
echo "# $DOMAIN 站点经验\n创建时间: $(date '+%Y-%m-%d %H:%M')\n\n## 经验内容\n$CONTENT" > "$FILE"
echo "✅ 已保存 $DOMAIN 的经验"
;;
get)
SAFE_DOMAIN=$(echo "$DOMAIN" | sed 's/[^a-zA-Z0-9.-]/_/g')
FILE="$EXPERIENCE_DIR/${SAFE_DOMAIN}.md"
[ -f "$FILE" ] && cat "$FILE" || echo "❌ 未找到 $DOMAIN 的经验"
;;
list)
echo "# 站点经验列表"
ls "$EXPERIENCE_DIR"/*.md 2>/dev/null | xargs -I{} basename {} .md || echo "(暂无记录)"
;;
esac
+42
View File
@@ -0,0 +1,42 @@
#!/bin/bash
# 检测用户是否在睡觉(1小时无对话)
LAST_ACTIVE_FILE="/tmp/openclaw-last-active.txt"
THRESHOLD_MINUTES=60
# 更新最后活动时间
update_active() {
date +%s > "$LAST_ACTIVE_FILE"
}
# 检查是否在睡眠(超过阈值无活动)
check_sleep() {
if [ ! -f "$LAST_ACTIVE_FILE" ]; then
# 首次运行,初始化
update_active
return 1
fi
last_active=$(cat "$LAST_ACTIVE_FILE")
now=$(date +%s)
diff=$(( (now - last_active) / 60 ))
if [ $diff -ge $THRESHOLD_MINUTES ]; then
return 0 # 在睡眠
else
return 1 # 醒着
fi
}
# 主逻辑
case "$1" in
"update")
update_active
;;
"check")
check_sleep
;;
*)
echo "Usage: $0 {update|check}"
;;
esac
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
# 守护者 睡眠学习配置
export ROBOT_NAME="守护者"
export ROBOT_TYPE="guardian"
exec /root/.openclaw/scripts/sleep-learning.sh "$@"
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
# 青龙 睡眠学习配置
export ROBOT_NAME="青龙"
export ROBOT_TYPE="qinglong"
exec /root/.openclaw/scripts/sleep-learning.sh "$@"
+118
View File
@@ -0,0 +1,118 @@
#!/bin/bash
# ============================================================================
# 睡眠自动学习脚本 - 调用标准学习模块版 v2.0
# ============================================================================
# 功能:守护者 & 青龙 通用版
# 特点:自动检测 + 调用learn-core模块
#
# 模式说明:
# source /root/.openclaw/scripts/learn-core.sh
# learn_topic "主题" "auto"
# ============================================================================
# -------------------- 加载标准学习模块 --------------------
source /root/.openclaw/scripts/learn-core.sh
# -------------------- 配置 --------------------
ROBOT_NAME="${ROBOT_NAME:-守护者}"
ROBOT_TYPE="${ROBOT_TYPE:-guardian}"
LOG_DIR="/var/log/openclaw/sleep-learning/${ROBOT_NAME}"
LOG_FILE="${LOG_DIR}/learning.log"
LEARNING_DIR="${LEARNING_DIR:-/root/.openclaw/workspace/sleep-learning}"
THRESHOLD_MINUTES=60
mkdir -p "$LOG_DIR" "$LEARNING_DIR"
# ============================================================================
# 初始化
# ============================================================================
init() {
echo "========================================"
echo "睡眠学习脚本启动"
echo "机器人: ${ROBOT_NAME} (${ROBOT_TYPE})"
echo "学习模块: learn-core.sh"
echo "========================================"
}
# ============================================================================
# 检测是否需要学习
# ============================================================================
should_learn() {
local last_active=$(cat /tmp/openclaw-last-active.txt 2>/dev/null)
local now=$(date +%s)
local last_time
if [ -n "$last_active" ]; then
last_time=$last_active
else
last_time=$now
fi
local diff=$((now - last_time))
local minutes=$((diff / 60))
if [ "$minutes" -ge "$THRESHOLD_MINUTES" ]; then
return 0 # 需要学习
else
echo "未满足学习条件:${minutes}分钟 < ${THRESHOLD_MINUTES}分钟"
return 1 # 不需要学习
fi
}
# ============================================================================
# 执行学习
# ============================================================================
run_learning() {
local topic="$1"
local type="${2:-auto}"
log_learn "开始学习: $topic (类型: $type)"
# 调用标准学习流程
learn_topic "$topic" "$type"
log_learn "学习完成"
}
# ============================================================================
# 主程序
# ============================================================================
main() {
init
if should_learn; then
echo ""
echo "🔄 开始自动学习..."
# 从青龙7大品类中选择
local category=$(choose_category)
log_learn "品类: $category"
# 调用学习模块
run_learning "$category" "auto"
else
echo "💤 进入睡眠模式"
fi
}
# ============================================================================
# 品类选择(轮询)
# ============================================================================
choose_category() {
local categories=(
"写作助手"
"贵金属交易"
"期货交易"
"合约交易"
"虚拟货币"
"网络自动化"
"AI能力提升"
)
# 随机选择或轮询
local index=$(($(date +%s) % 7))
echo "${categories[$index]}"
}
# 执行主程序
main "$@"
+100
View File
@@ -0,0 +1,100 @@
#!/bin/bash
# 网站SSL证书监控脚本
# 检测 hqbnb.com, hqbsh.com, szbjb.com, hqbsh.net, sjpdd.com 的HTTPS支持和证书有效期
# Telegram配置 (1号机token)
TELEGRAM_TOKEN="8529719199:AAGjLDflvMXAEdgrBTSBEczOoSMybLU4gcs"
TELEGRAM_CHAT_ID="5117446326"
# 监控网站列表
WEBSITES=("hqbnb.com" "hqbsh.com" "szbjb.com" "hqbsh.net" "sjpdd.com")
# 告警阈值(天数)
WARNING_DAYS=7
# 日志文件
LOG_FILE="/root/.openclaw/logs/ssl-monitor.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
send_telegram() {
local message="$1"
curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage" \
-d "chat_id=${TELEGRAM_CHAT_ID}" \
-d "text=${message}" \
-d "parse_mode=HTML" > /dev/null 2>&1
}
check_ssl() {
local domain="$1"
local result=""
# 提取证书信息
cert_info=$(echo | openssl s_client -servername "$domain" -connect "$domain":443 2>/dev/null | openssl x509 -noout -dates -subject 2>/dev/null)
if [ $? -ne 0 ]; then
echo "HTTPS_ERROR|$domain|无法连接到443端口"
return 1
fi
end_date=$(echo "$cert_info" | grep "notAfter" | cut -d= -f2)
end_date_epoch=$(date -d "$end_date" +%s 2>/dev/null)
current_epoch=$(date +%s)
days_left=$(($end_date_epoch - $current_epoch) / 86400 )
subject=$(echo "$cert_info" | grep "subject=" | cut -d= -f2-)
http_status=$(curl -s -o /dev/null -w "%{http_code}" -L --connect-timeout 10 "https://$domain" 2>/dev/null)
if [ "$http_status" == "200" ] || [ "$http_status" == "301" ] || [ "$http_status" == "302" ]; then
echo "HTTPS_OK|$domain|$days_left|$subject|$http_status"
return 0
else
echo "HTTPS_ERROR|$domain|HTTP状态码:$http_status"
return 1
fi
}
log "========== SSL证书检测开始 =========="
alert_message=""
success_count=0
error_count=0
for site in "${WEBSITES[@]}"; do
log "检测网站: $site"
result=$(check_ssl "$site")
status=$(echo "$result" | cut -d'|' -f1)
domain=$(echo "$result" | cut -d'|' -f2)
days_left=$(echo "$result" | cut -d'|' -f3)
subject=$(echo "$result" | cut -d'|' -f4)
http_code=$(echo "$result" | cut -d'|' -f5)
if [ "$status" == "HTTPS_OK" ]; then
success_count=$($success_count + 1)
log "✅ $site: HTTPS正常,证书还有 ${days_left} 天过期"
if [ "$days_left" -lt "$WARNING_DAYS" ]; then
log "⚠️ $site: 证书即将过期!仅剩 ${days_left} 天"
alert_message="${alert_message}⚠️ <b>$site</b> 证书即将过期 (${days_left}天)\n"
fi
else
error_count=$($error_count + 1)
log "❌ $site: HTTPS异常 - $result"
alert_message="${alert_message}❌ <b>$site</b> HTTPS异常: $result\n"
fi
done
log "检测完成: $success_count 成功, $error_count 错误"
if [ -n "$alert_message" ]; then
alert_message="🔔 <b>SSL证书监控告警</b>\n\n${alert_message}---\n检测时间: $(date '+%Y-%m-%d %H:%M:%S')"
log "发送Telegram告警..."
send_telegram "$alert_message"
fi
log "========== SSL证书检测完成 =========="
echo ""
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
CDP_PORT=18800
CHROME_PATH="/opt/google/chrome/chrome"
mkdir -p /tmp/openclaw-chrome
fuser -k /tcp 2>/dev/null || true
--remote-debugging-port= --remote-debugging-address=127.0.0.1 --user-data-dir=/tmp/openclaw-chrome --no-first-run --noerrdialogs --disable-gpu --no-sandbox --disable-dev-shm-usage --headless=new > /dev/null 2>&1 &
sleep 3
echo "✅ Chrome 启动完成 (CDP: )"
+50
View File
@@ -0,0 +1,50 @@
#!/bin/bash
# 模型路由自启动脚本
# 确保 OpenClaw Gateway 监听 18789,路由服务监听 18799
LOG_FILE="/root/.openclaw/workspace/memory/router.log"
ROUTER_PID_FILE="/tmp/model_router.pid"
start_router() {
if [ -f "$ROUTER_PID_FILE" ] && kill -0 $(cat "$ROUTER_PID_FILE") 2>/dev/null; then
echo "路由已在运行 (PID: $(cat $ROUTER_PID_FILE))"
return 0
fi
cd /root/.openclaw/workspace/models
nohup python3 model_router.py >> "$LOG_FILE" 2>&1 &
echo $! > "$ROUTER_PID_FILE"
sleep 2
if kill -0 $(cat "$ROUTER_PID_FILE") 2>/dev/null; then
echo "路由启动成功 (PID: $(cat $ROUTER_PID_FILE))"
else
echo "路由启动失败,查看日志: $LOG_FILE"
return 1
fi
}
stop_router() {
if [ -f "$ROUTER_PID_FILE" ]; then
kill $(cat "$ROUTER_PID_FILE") 2>/dev/null
rm -f "$ROUTER_PID_FILE"
echo "路由已停止"
fi
}
status_router() {
if [ -f "$ROUTER_PID_FILE" ] && kill -0 $(cat "$ROUTER_PID_FILE") 2>/dev/null; then
echo "路由运行中 (PID: $(cat $ROUTER_PID_FILE))"
curl -s http://127.0.0.1:18799/ 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print('端点:', len(d.get('endpoints',[])), '个')" 2>/dev/null || true
else
echo "路由未运行"
fi
}
case "$1" in
start) start_router ;;
stop) stop_router ;;
status) status_router ;;
restart) stop_router; start_router ;;
*) echo "用法: $0 {start|stop|status|restart}" ;;
esac
+238
View File
@@ -0,0 +1,238 @@
#!/bin/bash
# Optimized CPU & Memory Monitoring System v2.0
# Heartbeat: 10 seconds (light), 60 seconds (heavy)
# Features: Service health check, threshold alerts, session file monitoring
# Optimizations: Reduced frequency, /proc instead of top, separation of concerns
LOG_DIR="/var/log/openclaw-monitor"
LOG_FILE="${LOG_FILE:-$LOG_DIR/system-metrics.log}"
ALERT_LOG="${LOG_DIR}/alerts.log"
SESSION_LOG="${LOG_DIR}/session-alerts.log"
MAX_RECORDS=5400
INTERVAL_LIGHT=10 # 轻量监控间隔(秒)
INTERVAL_HEAVY=60 # 重量监控间隔(秒)
OPENCLAW_PORTS=("18789")
# 资源阈值
CPU_THRESHOLD=80
MEM_THRESHOLD=80
LOAD_THRESHOLD=4.0
# 会话文件监控阈值
SESSION_DIR="/root/.openclaw/agents/main/sessions"
SESSION_WARN_SIZE=$((8 * 1024 * 1024)) # 8MB 警告
SESSION_NEW_SESSION_SIZE=$((5 * 1024 * 1024)) # 5MB 开新会话
SESSION_MARKER_FILE="/tmp/openclaw-session-warn.json"
SESSION_NEW_SESSION_FILE="/tmp/openclaw-session-new.json"
LAST_CPU=""
LAST_MEM=""
LAST_LOAD=""
LAST_SESSION_SIZE=0
LAST_SESSION_CHECK=0
mkdir -p "$LOG_DIR"
# 轻量监控:CPU/内存/负载(高频)
check_light() {
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# CPU 使用率(使用 /proc/stat 更轻量)
local cpu_line=$(cat /proc/stat 2>/dev/null | grep '^cpu ' | head -1)
if [ -n "$cpu_line" ]; then
local cpu_idle=$(echo "$cpu_line" | awk '{print $5}')
# 简单估算:假设总时间是 idle + user + nice + system + iowait + irq + softirq
local cpu_total=$(echo "$cpu_line" | awk '{print $2+$3+$4+$5+$6+$7+$8}')
local cpu_usage="0.0"
if [ -n "$cpu_total" ] && [ "$cpu_total" != "0" ]; then
cpu_usage=$(awk "BEGIN {printf \"%.1f\", (($cpu_total - $cpu_idle) / $cpu_total) * 100}")
fi
else
# 回退到 top(极少情况)
cpu_usage=$(top -bn1 2>/dev/null | awk '/Cpu\(s\)/ {gsub(/,/, "", $2); print $2}' | head -1)
fi
# 内存信息
local mem_info=$(free -m 2>/dev/null | awk 'NR==2 {print $2,$3,$7}')
local mem_total=$(echo "$mem_info" | awk '{print $1}')
local mem_used=$(echo "$mem_info" | awk '{print $2}')
local mem_avail=$(echo "$mem_info" | awk '{print $3}')
local mem_usage="0.0"
if [ -n "$mem_total" ] && [ "$mem_total" != "0" ]; then
mem_usage=$(awk "BEGIN {printf \"%.1f\", ($mem_used)*100/$mem_total}")
fi
# 负载
local load_1m=$(cat /proc/loadavg | awk '{print $1}')
# 记录轻量日志
echo "LIGHT|${timestamp}|${cpu_usage}|${mem_usage}|${load_1m}" >> "$LOG_FILE"
# 检查阈值
check_thresholds "$timestamp" "$cpu_usage" "$mem_usage" "$load_1m"
}
# 重量监控:磁盘/会话文件(低频)
check_heavy() {
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# 交换空间
local swap_info=$(free -m 2>/dev/null | awk 'NR==3 {print $2,$3}')
local swap_total=$(echo "$swap_info" | awk '{print $1}')
local swap_used=$(echo "$swap_info" | awk '{print $2}')
local swap_usage="0.0"
if [ -n "$swap_total" ] && [ "$swap_total" != "0" ]; then
swap_usage=$(awk "BEGIN {printf \"%.1f\", ($swap_used)*100/$swap_total}")
fi
# 负载(完整)
local load_5m=$(cat /proc/loadavg | awk '{print $2}')
local load_15m=$(cat /proc/loadavg | awk '{print $3}')
# 磁盘
local disk_usage=$(df -h / 2>/dev/null | awk 'NR==2 {print $5}' | tr -d '%')
# OpenClaw 内存
local openclaw_mem="0.0"
local pids=$(pgrep -f "openclaw-gateway" 2>/dev/null)
if [ -n "$pids" ]; then
local sum=0
for pid in $pids; do
local rss=$(ps -o rss= -p "$pid" 2>/dev/null)
sum=$((sum + rss))
done
openclaw_mem=$(awk "BEGIN {printf \"%.1f\", $sum/1024}")
fi
# 服务状态
local service_status="DOWN"
for port in "${OPENCLAW_PORTS[@]}"; do
if ss -tlnp 2>/dev/null | grep -q ":${port} " || netstat -tlnp 2>/dev/null | grep -q ":${port} "; then
service_status="UP"
break
fi
done
# 记录重量日志
echo "HEAVY|${timestamp}|${swap_usage}|${load_5m}|${load_15m}|${disk_usage}|${openclaw_mem}|${service_status}" >> "$LOG_FILE"
# 检查服务状态
if [ "$service_status" = "DOWN" ]; then
echo "[CRITICAL] ${timestamp} OpenClaw SERVICE DOWN!" >> "$ALERT_LOG"
fi
# 检查会话文件(每60秒)
check_session_files "$timestamp"
}
check_session_files() {
if [ ! -d "$SESSION_DIR" ]; then
return
fi
# 获取当前主会话文件(最大文件)
local largest_file=""
local largest_size=0
local current_session_id=""
for file in "$SESSION_DIR"/*.jsonl; do
if [ -f "$file" ]; then
local size=$(stat -c%s "$file" 2>/dev/null || echo 0)
if [ "$size" -gt "$largest_size" ]; then
largest_size="$size"
largest_file="$file"
fi
fi
done
if [ "$largest_size" -eq 0 ] || [ -z "$largest_file" ]; then
return
fi
# 提取会话ID
current_session_id=$(basename "$largest_file" .jsonl)
# 8MB 警告
if [ "$largest_size" -ge "$SESSION_WARN_SIZE" ]; then
local size_mb=$(awk "BEGIN {printf \"%.1f\", $largest_size/1024/1024}")
local last_alert_size=$(cat "$SESSION_MARKER_FILE" 2>/dev/null | grep -o "\"warn\":[0-9]*" | grep -o "[0-9]*" || echo "0")
alert_threshold=$((last_alert_size / 1024 / 1024 + 1))
current_mb=$(echo "scale=1; $largest_size/1024/1024" | bc 2>/dev/null || echo "0")
if [ -n "$current_mb" ] && [ "$(echo "$current_mb >= $alert_threshold" | bc 2>/dev/null || echo "0")" -eq 1 ]; then
echo "[SESSION WARN] ${timestamp} 会话过大: ${current_session_id} (${size_mb}MB)" >> "$SESSION_LOG"
bash /root/.openclaw/scripts/send-session-alert.sh "warn" "$current_session_id" "$size_mb"
echo "{\"warn\":$largest_size,\"time\":\"$timestamp\"}" > "$SESSION_MARKER_FILE"
fi
fi
# 5MB 自动开新会话
if [ "$largest_size" -ge "$SESSION_NEW_SESSION_SIZE" ] && [ "$largest_size" -lt "$SESSION_WARN_SIZE" ]; then
local size_mb=$(awk "BEGIN {printf \"%.1f\", $largest_size/1024/1024}")
local last_processed=$(cat "$SESSION_NEW_SESSION_FILE" 2>/dev/null | grep -o "\"processed\":\"[^\"]*\"" | cut -d'"' -f4 || echo "")
if [ "$current_session_id" != "$last_processed" ]; then
echo "[SESSION NEW] ${timestamp} 会话超5MB: ${current_session_id} (${size_mb}MB)" >> "$SESSION_LOG"
bash /root/.openclaw/scripts/send-session-alert.sh "new" "$current_session_id" "$size_mb"
echo "{\"warn\":0,\"processed\":\"$current_session_id\",\"time\":\"$timestamp\"}" > "$SESSION_NEW_SESSION_FILE"
fi
fi
}
check_thresholds() {
local ts="$1" cpu="$2" mem="$3" load="$4"
# CPU 检查
cpu=$(echo "$cpu" | tr -d ' ')
if [ -n "$cpu" ] && [ "$cpu" != "0.0" ]; then
local cpu_high=$(awk "BEGIN {print ($cpu > $CPU_THRESHOLD) ? 1 : 0}")
if [ "$cpu_high" = "1" ] && [ "$LAST_CPU" != "HIGH" ]; then
echo "[ALERT] ${ts} CPU HIGH: ${cpu}% (threshold: ${CPU_THRESHOLD}%)" >> "$ALERT_LOG"
fi
LAST_CPU="$([ "$cpu_high" = "1" ] && echo "HIGH" || echo "NORMAL")"
fi
# 内存检查
if [ -n "$mem" ] && [ "$mem" != "0.0" ]; then
local mem_high=$(awk "BEGIN {print ($mem > $MEM_THRESHOLD) ? 1 : 0}")
if [ "$mem_high" = "1" ] && [ "$LAST_MEM" != "HIGH" ]; then
echo "[ALERT] ${ts} MEM HIGH: ${mem}%" >> "$ALERT_LOG"
fi
LAST_MEM="$([ "$mem_high" = "1" ] && echo "HIGH" || echo "NORMAL")"
fi
# 负载检查
if [ -n "$load" ]; then
local load_high=$(awk "BEGIN {print ($load > $LOAD_THRESHOLD) ? 1 : 0}")
if [ "$load_high" = "1" ] && [ "$LAST_LOAD" != "HIGH" ]; then
echo "[ALERT] ${ts} LOAD HIGH: ${load} (threshold: ${LOAD_THRESHOLD})" >> "$ALERT_LOG"
fi
LAST_LOAD="$([ "$load_high" = "1" ] && echo "HIGH" || echo "NORMAL")"
fi
}
cleanup() {
local line_count=$(wc -l < "$LOG_FILE" 2>/dev/null || echo 0)
if [ "$line_count" -gt "$MAX_RECORDS" ]; then
local to_remove=$((line_count - MAX_RECORDS))
sed -i "1,${to_remove}d" "$LOG_FILE" 2>/dev/null
fi
}
trap cleanup EXIT
echo "[INFO] $(date '+%Y-%m-%d %H:%M:%S') 监控启动 (light:${INTERVAL_LIGHT}s, heavy:${INTERVAL_HEAVY}s)"
counter=0
while true; do
# 轻量监控每次都执行
check_light
# 计数器:每6次(60秒)执行一次重量监控
counter=$((counter + 1))
if [ $counter -ge 6 ]; then
check_heavy
counter=0
fi
cleanup
sleep $INTERVAL_LIGHT
done
+83
View File
@@ -0,0 +1,83 @@
#!/bin/bash
#
# 故障趋势分析脚本
# 用途: 分析历史故障数据,识别趋势
#
ALERT_LOG="/var/log/openclaw-monitor/alerts.log"
REPORT_FILE="/var/log/openclaw/trend-analysis.log"
echo "========================================" >> "$REPORT_FILE"
echo "故障趋势分析报告" >> "$REPORT_FILE"
echo "生成时间: $(date '+%Y-%m-%d %H:%M:%S')" >> "$REPORT_FILE"
echo "========================================" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
# 1. 最近7天统计
echo "【最近7天统计】" >> "$REPORT_FILE"
echo "---------------------------" >> "$REPORT_FILE"
for i in {0..6}; do
DATE=$(date -d "-$i days" +%Y-%m-%d)
COUNT=$(grep -c "$DATE" "$ALERT_LOG" 2>/dev/null || echo 0)
echo "$DATE: $COUNT 条" >> "$REPORT_FILE"
done
echo "" >> "$REPORT_FILE"
# 2. 故障类型分布
echo "【故障类型分布】" >> "$REPORT_FILE"
echo "---------------------------" >> "$REPORT_FILE"
CRITICAL=$(grep -c "CRITICAL" "$ALERT_LOG" 2>/dev/null || echo 0)
ALERT=$(grep -c "ALERT" "$ALERT_LOG" 2>/dev/null || echo 0)
AUTO=$(grep -c "AUTO" "$ALERT_LOG" 2>/dev/null || echo 0)
TOTAL=$((CRITICAL + ALERT + AUTO))
echo "CRITICAL: $CRITICAL ($((CRITICAL * 100 / TOTAL))%)" >> "$REPORT_FILE"
echo "ALERT: $ALERT ($((ALERT * 100 / TOTAL))%)" >> "$REPORT_FILE"
echo "AUTO: $AUTO ($((AUTO * 100 / TOTAL))%)" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"
# 3. 趋势判断
echo "【趋势分析】" >> "$REPORT_FILE"
echo "---------------------------" >> "$REPORT_FILE"
# 计算最近3天平均
RECENT_AVG=$(tail -3 "$REPORT_FILE" | grep "条" | awk '{sum+=$2} END {if (NR>0) print sum/NR; else print 0}')
if [ -n "$RECENT_AVG" ]; then
echo "最近3天平均: $RECENT_AVG 条/天" >> "$REPORT_FILE"
fi
# 趋势判断
LAST_DAY=$(tail -1 "$REPORT_FILE" | grep "条" | awk '{print $2}')
PREV_DAY=$(tail -2 "$REPORT_FILE" | grep "条" | tail -1 | awk '{print $2}')
if [ -n "$LAST_DAY" ] && [ -n "$PREV_DAY" ]; then
DIFF=$((LAST_DAY - PREV_DAY))
if [ "$DIFF" -gt 0 ]; then
echo "趋势: 📈 上升 ($DIFF 条)" >> "$REPORT_FILE"
elif [ "$DIFF" -lt 0 ]; then
echo "趋势: 📉 下降 ($((-DIFF)) 条)" >> "$REPORT_FILE"
else
echo "趋势: ➡️ 持平" >> "$REPORT_FILE"
fi
fi
echo "" >> "$REPORT_FILE"
# 4. 建议
echo "【建议】" >> "$REPORT_FILE"
echo "---------------------------" >> "$REPORT_FILE"
# 基于分析给出建议
if [ "$CRITICAL" -gt 100 ]; then
echo "⚠️ CRITICAL 告警较多,建议检查系统稳定性" >> "$REPORT_FILE"
fi
if [ "$AUTO" -gt 500 ]; then
echo "ℹ️ AUTO 告警较多,可能是自动恢复机制触发" >> "$REPORT_FILE"
fi
if [ "$LAST_DAY" -gt 100 ]; then
echo "📊 今日告警较多,建议关注" >> "$REPORT_FILE"
fi
echo "" >> "$REPORT_FILE"
echo "趋势分析完成: $REPORT_FILE"