Skill: cxlhyx/agent-manager-hxx (version 1.0.0)

--- name: agent-manager description: 管理 OpenClaw 系统中的 Agent 生命周期，包括 Agent 配置、Matrix 账号注册、账号绑定等操作。 --- # Agent Manager 用于管理 OpenClaw 系统中 Agent 的完整生命周期，包括 Agent 配置、Matrix 账号注册、账号绑定等操作。 ## 功能概述 - **Agent 配置管理**: 添加、移除、列出 Agent 配置 - **Matrix 账号管理**: 注册新账号、添加、移除 Matrix 账号 - **绑定管理**: 建立 Agent 与 Matrix 账号的关联 - **一键设置**: 自动化完成整个 Agent 设置流程 ## 脚本说明 ### 1. setup_agent.sh - 一键设置脚本 完整设置流程，自动完成以下步骤： 1. 添加 Agent 配置到 openclaw.json 2. 在 Matrix 服务器注册账号 3. 将账号添加到 openclaw.json 配置 4. 绑定 Agent 与 Matrix 账号 **用法:** ```bash bash scripts/setup_agent.sh <agent_id> <agent_name> ``` **参数:** - `agent_id`: Agent 的唯一标识（如: juezhi） - `agent_name`: Agent 的显示名称（如: 货绝知） **环境变量:** - `HOMESERVER_URL`: Matrix 服务器地址（默认: http://localhost:8008） - `CONFIG_PATH`: openclaw.json 配置文件路径（默认: ~/.openclaw/openclaw.json） **示例:** ```bash # 默认设置 bash scripts/setup_agent.sh "huojuezhi" "货绝知" # 指定 Matrix 服务器 HOMESERVER_URL=http://192.168.1.100:8008 bash scripts/setup_agent.sh "huojuezhi" "货绝知" ``` --- ### 2. config_manager.py - 配置管理器 用于直接管理 openclaw.json 配置文件。 **用法:** ```bash python3 scripts/config_manager.py <command> [options] ``` #### Agent 管理 ```bash # 列出所有 Agent python3 scripts/config_manager.py agents list # 添加 Agent python3 scripts/config_manager.py agents add <name> [id] [workspace] [model] # 移除 Agent python3 scripts/config_manager.py agents remove <name> ``` #### Matrix 账号管理 ```bash # 列出所有 Matrix 账号 python3 scripts/config_manager.py accounts list # 添加 Matrix 账号 python3 scripts/config_manager.py accounts add <name> <accesstoken> [id] [homeserver] [userId] [dm_policy] # 移除 Matrix 账号 python3 scripts/config_manager.py accounts remove <name> ``` #### 绑定管理 ```bash # 列出所有绑定 python3 scripts/config_manager.py bindings list # 添加绑定 python3 scripts/config_manager.py bindings add <agentId> <accountId> [channel] # 移除绑定 python3 scripts/config_manager.py bindings remove <agentId> <accountId> ``` --- ### 3. matrix_register.sh - Matrix 账号注册 用于在 Matrix 服务器上注册新账号并获取 Access Token。 **用法:** ```bash bash scripts/matrix_register.sh <username> <password> ``` **环境变量:** - `HOMESERVER_URL`: Matrix 服务器地址（默认: http://localhost:8008） **输出格式:** ``` RESULT_USER_ID: @username:homeserver RESULT_ACCESS_TOKEN: syt_xxxxx... ``` **示例:** ```bash # 注册账号 HOMESERVER_URL=http://192.168.1.100:8008 bash scripts/matrix_register.sh "huojuezhi" "password123" ``` --- ## 配置文件 配置文件默认路径: `~/.openclaw/openclaw.json` 配置文件结构: - `agents`: Agent 列表配置 - `channels.matrix.accounts`: Matrix 账号配置 - `bindings`: Agent 与账号的绑定关系 ## 依赖 - Python 3 - pypinyin (用于将中文名转为拼音 ID) - curl (用于 Matrix API 调用)

path: scripts/config_manager.py
content: #!/usr/bin/env python3
"""
OpenClaw 配置管理器
用于读取、修改和保存 openclaw.json 配置文件
"""

import json
import sys
import os
import pypinyin
from pathlib import Path

# 默认配置文件路径
DEFAULT_CONFIG_PATH = Path.home() / ".openclaw" / "openclaw.json"


def load_config(config_path=None):
    """加载配置文件"""
    path = Path(config_path) if config_path else DEFAULT_CONFIG_PATH
    if not path.exists():
        print(f"❌ 配置文件不存在: {path}")
        return None

    try:
        with open(path, "r", encoding="utf-8") as f:
            return json.load(f)
    except json.JSONDecodeError as e:
        print(f"❌ JSON解析错误: {e}")
        return None
    except Exception as e:
        print(f"❌ 读取失败: {e}")
        return None


def save_config(config, config_path=None):
    """保存配置文件"""
    path = Path(config_path) if config_path else DEFAULT_CONFIG_PATH

    try:
        # 确保目录存在
        path.parent.mkdir(parents=True, exist_ok=True)

        with open(path, "w", encoding="utf-8") as f:
            json.dump(config, f, ensure_ascii=False, indent=2)
        print(f"✅ 配置已保存到: {path}")
        return True
    except Exception as e:
        print(f"❌ 保存失败: {e}")
        return False


def list_agents(config):
    """列出所有已配置的agent"""
    agents = config.get("agents", {}).get("list", [])
    if not agents:
        print("📭 当前没有配置任何agent")
        return

    print(f"📋 已配置的agent（共{len(agents)}个）：")
    for i, agent in enumerate(agents, 1):
        agent_id = agent.get("id", "N/A")
        agent_name = agent.get("name", "N/A")
        agent_workspace = agent.get("workspace", "N/A")
        agent_model = agent.get("model", "N/A")
        print(
            f"  {i}. {agent_id} (名称: {agent_name}, 工作目录: {agent_workspace}, 模型: {agent_model})"
        )


def add_agent(config, agent_id, agent_name, agent_workspace, model):
    """添加新agent到配置"""
    # 检查是否已存在
    for agent in config.get("agents", {}).get("list", []):
        if agent.get("id") == agent_id:
            print(f"⚠️ agent '{agent_id}' 已存在")
            return False

    if model == "default":
        model = (
            config.get("agents", {}).get("defaults", {}).get("model", {}).get("primary")
        )

    new_agent = {
        "id": agent_id,
        "name": agent_name,
        "workspace": agent_workspace,
        "model": model,
    }
    config["agents"]["list"].append(new_agent)
    print(f"✅ agent '{agent_id}' 已添加到配置")
    return True


def remove_agent(config, agent_name):
    """从配置中移除agent"""
    agent_id = None
    for agent in config.get("agents", {}).get("list", []):
        if agent.get("name") == agent_name:
            agent_id = agent.get("id")
            break

    if not agent_id:
        print(f"📭 当前没有配置agent '{agent_name}'")
        return False

    original_len = len(config["agents"]["list"])
    config["agents"]["list"] = [
        a for a in config["agents"]["list"] if a.get("id") != agent_id
    ]

    if len(config["agents"]["list"]) < original_len:
        print(f"✅ agent '{agent_name}' 已从配置移除")
        return True
    else:
        print(f"⚠️ agent '{agent_name}' 移除发生错误")
        return False


def list_accounts(config):
    """列出所有已配置的Matrix账号"""
    accounts = config.get("channels", {}).get("matrix", {}).get("accounts", {})
    if not accounts:
        print("📭 当前没有配置Matrix账号")
        return

    print(f"📋 已配置的Matrix账号（共{len(accounts)}个）：")
    for i, account in enumerate(accounts, 1):
        info = accounts.get(account, {})
        account_id = account
        account_name = info.get("name", "N/A")
        account_homeserver = info.get("homeserver", "N/A")
        account_user_id = info.get("userId", "N/A")
        account_dm_policy = info.get("dm", "N/A").get("policy", "N/A")
        print(
            f"  {i}. {account_id} ({account_name}) → {account_user_id}@{account_homeserver} (DM_Policy: {account_dm_policy})"
        )


def add_matrix_account(
    config,
    account_id,
    account_name,
    account_homeserver,
    account_user_id,
    account_access_token,
    account_dm_policy,
):
    """添加Matrix账号到配置"""
    accounts = config.get("channels", {}).get("matrix", {}).get("accounts", {})
    if account_id in accounts:
        print(f"⚠️ 账号 '{account_id}' 已存在")
        return False

    new_account = {
        "name": account_name,
        "homeserver": account_homeserver,
        "accessToken": account_access_token,
        "userId": account_user_id,
        "dm": {"policy": account_dm_policy},
    }
    accounts[account_id] = new_account
    print(f"✅ Matrix账号 '{account_user_id}' 已添加到配置")
    return True


def remove_matrix_account(config, account_name):
    """从配置中移除Matrix账号"""
    accounts = config.get("channels", {}).get("matrix", {}).get("accounts", {})
    account_id = None
    for acc_id, info in accounts.items():
        if info.get("name") == account_name:
            account_id = acc_id
            break

    if not account_id:
        print(f"📭 当前没有配置账号 '{account_name}'")
        return False

    del accounts[account_id]
    print(f"✅ Matrix账号 '{account_name}' 已从配置移除")
    return True


def list_bindings(config):
    """列出所有agent与账号的绑定关系"""
    bindings = config.get("bindings", [])
    if not bindings:
        print("📭 当前没有配置绑定关系")
        return

    print(f"📋 agent与Matrix账号绑定（共{len(bindings)}个）：")
    for i, binding in enumerate(bindings, 1):
        agent_id = binding.get("agentId", "N/A")
        channel = binding.get("match", {}).get("channel", "N/A")
        account_id = binding.get("match", {}).get("accountId", "N/A")
        print(f"  {i}. {agent_id} → {account_id} (Channel: {channel})")


def add_binding(config, agent_id, account_id, channel=None):
    """添加agent与Matrix账号的绑定"""
    # 检查agent是否存在
    agent_exists = any(
        a.get("id") == agent_id for a in config.get("agents", {}).get("list", [])
    )
    if not agent_exists:
        print(f"⚠️ agent '{agent_id}' 不存在，请先添加agent")
        return False

    # 检查账号是否存在
    account_exists = any(
        acc_id == account_id
        for acc_id, info in config.get("channels", {})
        .get("matrix", {})
        .get("accounts", {})
        .items()
    )
    if not account_exists:
        print(f"⚠️ Matrix账号 '{account_id}' 不存在，请先添加账号")
        return False

    # 检查是否已绑定
    for binding in config["bindings"]:
        if binding.get("agentId") == agent_id:
            print(
                f"⚠️ agent '{agent_id}' 已绑定到账号 '{binding.get('match', {}).get('accountId')}'"
            )
            return False

    new_binding = {
        "agentId": agent_id,
        "match": {"channel": channel, "accountId": account_id},
    }
    config["bindings"].append(new_binding)
    print(f"✅ agent '{agent_id}' 已绑定到Matrix账号 '{account_id}'")
    return True


def remove_binding(config, agent_id, account_id):
    """移除agent与Matrix账号的绑定"""
    bindings = config.get("bindings", [])
    original_len = len(bindings)
    config["bindings"] = [
        b
        for b in bindings
        if not (
            b.get("agentId") == agent_id
            and b.get("match", {}).get("accountId") == account_id
        )
    ]

    if len(config["bindings"]) < original_len:
        print(f"✅ agent '{agent_id}' 与账号 '{account_id}' 的绑定已移除")
        return True
    else:
        print(f"⚠️ 没有找到agent '{agent_id}' 与账号 '{account_id}' 的绑定")
        return False


def main():
    if len(sys.argv) < 2:
        print(
            """OpenClaw 配置管理器

用法:
  config_manager.py agents list                                                                   - 列出所有agent
  config_manager.py agents add <name> [id] [workspace] [model]                                    - 添加agent
  config_manager.py agents remove <name>                                                          - 移除agent
  
  config_manager.py accounts list                                                                 - 列出所有Matrix账号
  config_manager.py accounts add <name> <accesstoken> [id] [homeserver] [userId] [dm_policy]      - 添加账号
  config_manager.py accounts remove <name>                                                        - 移除账号
  
  config_manager.py bindings list                                                                 - 列出所有绑定
  config_manager.py bindings add <agentId> <accountId> [channel]                                  - 添加绑定
  config_manager.py bindings remove <agentId> <accountId>                                         - 移除绑定
  
示例:
  config_manager.py agents add huojuezhi
  config_manager.py accounts add huojuezhi syt_xxx
  config_manager.py bindings add huojuezhi huojuezhi matrix
"""
        )
        sys.exit(1)

    command = sys.argv[1]
    config = load_config()

    if config is None:
        sys.exit(1)

    modified = False

    if command == "agents":
        if len(sys.argv) < 3:
            print("错误：请提供子命令 (list/add/remove)")
            sys.exit(1)

        subcmd = sys.argv[2]

        if subcmd == "list":
            list_agents(config)

        elif subcmd == "add":
            if len(sys.argv) < 4:
                print("错误：请提供agent 名称")
                sys.exit(1)
            agent_name = sys.argv[3]
            agent_id = (
                sys.argv[4]
                if len(sys.argv) > 4
                else pypinyin.slug(agent_name, separator="")
            )
            agent_workspace = (
                sys.argv[5]
                if len(sys.argv) > 5
                else f"{Path.home()}/.openclaw/{agent_id}-workspace"
            )
            model = sys.argv[6] if len(sys.argv) > 6 else "default"
            modified = add_agent(config, agent_id, agent_name, agent_workspace, model)

        elif subcmd == "remove":
            if len(sys.argv) < 4:
                print("错误：请提供agent 名称")
                sys.exit(1)
            agent_name = sys.argv[3]
            modified = remove_agent(config, agent_name)

        else:
            print(f"未知子命令: {subcmd}")
            sys.exit(1)

    elif command == "accounts":
        if len(sys.argv) < 3:
            print("错误：请提供子命令 (list/add)")
            sys.exit(1)

        subcmd = sys.argv[2]

        if subcmd == "list":
            list_accounts(config)

        elif subcmd == "add":
            if len(sys.argv) < 5:
                print("错误：请提供 name, accessToken")
                sys.exit(1)
            account_name = sys.argv[3]
            account_access_token = sys.argv[4]
            account_id = (
                sys.argv[5]
                if len(sys.argv) > 5
                else pypinyin.slug(account_name, separator="")
            )
            account_homeserver = (
                sys.argv[6] if len(sys.argv) > 6 else "http://localhost:8008"
            )
            account_user_id = (
                sys.argv[7] if len(sys.argv) > 7 else f"@{account_id}:matrix.local"
            )
            account_dm_policy = sys.argv[8] if len(sys.argv) > 8 else "pairing"
            modified = add_matrix_account(
                config,
                account_id,
                account_name,
                account_homeserver,
                account_user_id,
                account_access_token,
                account_dm_policy,
            )

        elif subcmd == "remove":
            if len(sys.argv) < 4:
                print("错误：请提供 account 名称")
                sys.exit(1)
            account_name = sys.argv[3]
            modified = remove_matrix_account(config, account_name)

        else:
            print(f"未知子命令: {subcmd}")
            sys.exit(1)

    elif command == "bindings":
        if len(sys.argv) < 3:
            print("错误：请提供子命令 (list/add)")
            sys.exit(1)

        subcmd = sys.argv[2]

        if subcmd == "list":
            list_bindings(config)

        elif subcmd == "add":
            if len(sys.argv) < 5:
                print("错误：请提供 agent ID 和 account userId")
                sys.exit(1)
            agent_id = sys.argv[3]
            account_id = sys.argv[4]
            channel = sys.argv[5] if len(sys.argv) > 5 else "matrix"
            modified = add_binding(config, agent_id, account_id, channel=channel)

        elif subcmd == "remove":
            if len(sys.argv) < 5:
                print("错误：请提供 agent ID 和 account userId")
                sys.exit(1)
            agent_id = sys.argv[3]
            account = sys.argv[4]
            modified = remove_binding(config, agent_id, account)

        else:
            print(f"未知子命令: {subcmd}")
            sys.exit(1)

    else:
        print(f"未知命令: {command}")
        sys.exit(1)

    # 如果有修改，保存配置
    if modified:
        if save_config(config):
            sys.exit(0)  # 明确成功
        else:
            sys.exit(1)  # 保存失败
    else:
        # 如果是因为已存在等原因导致 modified 为 False
        # 且该操作是关键路径，建议也退出 1
        print("❌ 操作未完成或无变更")
        sys.exit(1)


if __name__ == "__main__":
    main()


path: scripts/matrix_register.sh
content: #!/bin/bash

# 配置：如果有环境变量则使用，否则默认本地
HOMESERVER_URL="${HOMESERVER_URL:-http://localhost:8008}"

# 简易 JSON 提取函数（只提取双引号内的值）
extract_val() {
    local key="$1"
    local json="$2"
    echo "$json" | sed -n "s/.*\"$key\":\"\([^\"]*\)\".*/\1/p" | head -n 1
}

# 1. 注册账号
register_user() {
    local user="$1"
    local pass="$2"
    
    echo "--- 正在尝试注册: $user ---"
    # 直接使用你提供的 v3 接口和 payload
    local resp=$(curl -s -X POST "${HOMESERVER_URL}/_matrix/client/v3/register" \
        -H "Content-Type: application/json" \
        -d "{
            \"username\": \"$user\",
            \"password\": \"$pass\",
            \"auth\": {\"type\": \"m.login.dummy\"}
        }")
    
    local err=$(extract_val "errcode" "$resp")
    if [ -z "$err" ]; then
        echo "注册成功！"
    else
        echo "注册反馈: $err (可能账号已存在，将尝试直接登录)"
    fi
}

# 2. 获取 Access Token
get_token() {
    local user="$1"
    local pass="$2"
    
    echo "--- 正在获取 Access Token ---"
    # 使用你提供的登录接口
    local resp=$(curl -s -X POST "${HOMESERVER_URL}/_matrix/client/v3/login" \
        -H "Content-Type: application/json" \
        -d "{
            \"type\": \"m.login.password\",
            \"identifier\": {\"type\": \"m.id.user\", \"user\": \"$user\"},
            \"password\": \"$pass\"
        }")

    local [REDACTED_SECRET] "access_token" "$resp")
    local full_uid=$(extract_val "user_id" "$resp")

    if [ -n "$token" ]; then
        # 建议这里只打印结果，不要有其他干扰字符，或者用特定格式
        echo "RESULT_USER_ID: $full_uid"
        echo "RESULT_ACCESS_TOKEN: $token"
    else
        echo "错误：无法获取 Token" >&2 # 输出到错误流
        exit 1
    fi
}

# 执行逻辑
if [ -z "$2" ]; then
    echo "用法: $0 <用户id> <密码>"
    exit 1
fi

register_user "$1" "$2"
get_token "$1" "$2"

path: scripts/setup_agent.sh
content: #!/bin/bash
# Agent 完整设置脚本
# 一键完成：添加agent配置 -> 注册Matrix账号 -> 添加账号到配置 -> 绑定agent与账号

set -e

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# 脚本目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"

# 默认配置
HOMESERVER_URL="${HOMESERVER_URL:-http://localhost:8008}"
CONFIG_PATH="${CONFIG_PATH:-$HOME/.openclaw/openclaw.json}"

# 显示帮助
show_help() {
    cat << EOF
Agent 完整设置脚本

用法:
  $0 <agent_id> <agent_name>

参数:
  agent_id     - agent的唯一标识（如: juezhi）
  agent_name   - agent的显示名称（如: 货绝知）
    
环境变量:
  HOMESERVER_URL  - Matrix服务器地址
  CONFIG_PATH     - openclaw.json配置文件路径

示例:
  $0 "huojuezhi" "货绝知"
  HOMESERVER_URL=http://192.168.1.100:8008 $0 "huojuezhi" "货绝知"

流程:
  1. 添加agent到openclaw.json配置
  2. 在Matrix服务器注册账号
  3. 将账号添加到openclaw.json配置
  4. 绑定agent与Matrix账号
EOF
}

# 主函数
main() {
    if [ $# -lt 2 ]; then
        show_help
        exit 1
    fi
    
    local agent_id="$1"
    local agent_name="$2"
    shift 2
    
    echo -e "${BLUE}═══════════════════════════════════════${NC}"
    echo -e "${BLUE}  Agent 设置向导${NC}"
    echo -e "${BLUE}═══════════════════════════════════════${NC}"
    echo ""
    echo "配置信息:"
    echo "  Agent ID: $agent_id"
    echo "  Agent名称: $agent_name"
    echo "  Matrix服务器: $HOMESERVER_URL"
    echo "  配置文件: $CONFIG_PATH"
    echo ""
    
    # 检查依赖
    if ! command -v python3 &> /dev/null; then
        echo -e "${RED}❌ 需要安装 python3${NC}"
        exit 1
    fi
    
    # 步骤1: 添加agent配置
    echo -e "${YELLOW}步骤 1/4: 添加agent配置...${NC}"
    if ! python3 "$SCRIPT_DIR/config_manager.py" agents add "$agent_name" "$agent_id" "$HOME/.openclaw/${agent_id}-workspace" "nvidia/moonshotai/kimi-k2.5"; then
        echo -e "${RED}❌ 步骤1失败：无法添加Agent配置。${NC}"
        exit 1
    fi

    # 步骤2: 注册Matrix账号
    echo -e "${YELLOW}步骤 2/4: 注册/登录Matrix账号...${NC}"
    local [REDACTED_SECRET]"
    local register_output
    # 捕获输出
    if ! register_output=$(HOMESERVER_URL="$HOMESERVER_URL" bash "$SCRIPT_DIR/matrix_register.sh" "$agent_id" "$password" 2>&1); then
        echo -e "${RED}❌ 步骤2失败：Matrix注册或登录过程出错。${NC}"
        echo "$register_output"
        exit 1
    fi
    
    # 解析 Token 和 UID (增加容错)
    local access_token=$(echo "$register_output" | grep "RESULT_ACCESS_TOKEN:" | awk '{print $NF}')
    local user_id=$(echo "$register_output" | grep "RESULT_USER_ID:" | awk '{print $NF}')

    if [[ -z "$access_token" || -z "$user_id" ]]; then
        echo -e "${RED}❌ 步骤2失败：解析Token失败。原始输出：${NC}\n$register_output"
        exit 1
    fi
    echo -e "${GREEN}成功获取 Token 为: ${access_token:0:8}...${NC}"

    # 步骤3: 添加账号到配置
    echo -e "${YELLOW}步骤 3/4: 添加Matrix账号到配置...${NC}"
    if ! python3 "$SCRIPT_DIR/config_manager.py" accounts add "$agent_name" "$access_token" "$agent_id" "$HOMESERVER_URL" "$user_id" "pairing"; then
        echo -e "${RED}❌ 步骤3失败：无法将账号写入配置文件。${NC}"
        exit 1
    fi

    # 步骤4: 绑定agent与账号
    echo -e "${YELLOW}步骤 4/4: 绑定agent与Matrix账号...${NC}"
    if ! python3 "$SCRIPT_DIR/config_manager.py" bindings add "$agent_id" "$agent_id" "matrix"; then
        echo -e "${RED}❌ 步骤4失败：绑定关系建立失败。${NC}"
        exit 1
    fi

    # 初始化工作空间
    cp -r "${HOME}/.openclaw/tmp-workspace/." "${HOME}/.openclaw/${agent_id}-workspace"

    # 完成
    echo -e "${GREEN}═══════════════════════════════════════${NC}"
    echo -e "${GREEN}  ✅ Agent设置完成！${NC}"
    echo -e "${GREEN}═══════════════════════════════════════${NC}"
    echo ""
    echo "总结:"
    echo "  Agent ID: $agent_id"
    echo "  显示名: $agent_name"
    echo "  Matrix账号: $user_id"
    echo "  配置文件: $CONFIG_PATH"
    echo ""
    echo -e "${YELLOW}⚠️ 请保存以下密码（仅在本次显示）:${NC}"
    echo "  密码: $password"
}

main "$@"


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)