---
name: sophnet-bot-client
description: |
  为代理配置远程 Bot API 连接。支持两种模式：
  - raw: 注入 curl 模板（无权限强制）
  - proxy: 注入权限代理，程序化权限检查（推荐）
commands:
  - /bot-client setup — 配置远程连接
  - /bot-client remove — 移除远程连接
metadata:
  openclaw:
    emoji: "🔗"
    requires:
      bins: ["uv"]
      env: []
---

# Bot API Client Skill

为代理注入远程协作能力。

**两种模式：**

- **raw**（旧模式）：将 curl 模板 + 凭据路径写入 AGENTS.md，代理直接用 curl 对话。权限仅靠 LLM 文本约束。
- **proxy**（推荐）：通过 `bot_client_safe.sh` → `bot_client_proxy.py` 代理链路，**程序化检查权限后**再转发请求。凭据对代理不可见。

## 强制要求：工作目录

**所有命令必须在本 skill 目录下执行：**

```bash
SKILL_DIR="<本skill的sophnet-bot-client目录绝对路径>"
cd "$SKILL_DIR"
```

## Python 运行环境（uv）

**所有 Python 执行必须使用 `uv run --project .`，禁止直接使用 `python` 或 `pip install`。**

首次使用需初始化：

```bash
cd "$SKILL_DIR" && uv sync --project .
```

---

## Processing Mode

**STRICT SERIAL PROCESSING ONLY** — 按顺序逐步执行，不要拆分子任务或并行处理。

---

## 命令参考

### setup — 配置远程连接

**proxy 模式（推荐）：**

```bash
cd "$SKILL_DIR" && uv run --project . python scripts/bot_client_setup.py setup \
  --agent-id "<本地代理 ID>" \
  --url "https://{远端 Sophnet 实例域名}/bot-api/v2/{远端 account_id}/chat" \
  --secret "<远端 api_secret>" \
  --remote-agent-id "<远端 agent ID>" \
  --mode proxy
```

**raw 模式（旧模式）：**

```bash
cd "$SKILL_DIR" && uv run --project . python scripts/bot_client_setup.py setup \
  --agent-id "<本地代理 ID>" \
  --url "https://{远端 Sophnet 实例域名}/bot-api/v2/{远端 account_id}/chat" \
  --secret "<远端 api_secret>" \
  --remote-agent-id "<远端 agent ID>"
```

| 参数                | 必填 | 说明                                                         |
| ------------------- | ---- | ------------------------------------------------------------ |
| `--agent-id`        | 是   | **本地**代理 ID                                              |
| `--url`             | 是   | **远端** Bot API URL，格式为 `https://{远端 Sophnet 实例域名}/bot-api/v2/{远端 account_id}/chat` |
| `--secret`          | 是   | **远端** API Secret（Bearer token）                          |
| `--remote-agent-id` | 是   | **远端**目标 agent ID                                        |
| `--mode`            | 否   | `proxy`（默认）或 `raw`（旧模式）；**必须用 `proxy`，`raw` 模式下 credentials 写到错误位置，激活检查永远不通过** |

**proxy 模式执行逻辑：**

1. 在 admin_dir（`/home/node/.config/sophnet-customer-admin/<agent-id>/`）中保存凭据（对代理不可见）
2. 在 AGENTS.md 追加「远程协作」章节（仅包含 `bot_client_safe.sh` 调用模板，无 curl/凭据）
3. 将 `bot_client_safe.sh` 添加到 exec 白名单
4. 设置 AGENTS.md 为只读（chmod 444）
5. 幂等：重复执行会替换已有章节和凭据

**raw 模式执行逻辑：**

1. 在代理 workspace 的 `data/bot_credentials.json` 中保存凭据
2. 在 AGENTS.md 末尾追加「远程协作」章节（含 curl 模板、会话管理指令）
3. 幂等：重复执行会替换已有章节和凭据

### remove — 移除远程连接

```bash
cd "$SKILL_DIR" && uv run --project . python scripts/bot_client_setup.py remove \
  --agent-id "<本地代理 ID>"
```

| 参数         | 必填 | 说明            |
| ------------ | ---- | --------------- |
| `--agent-id` | 是   | **本地**代理 ID |

**执行逻辑：**

1. 从该代理的 AGENTS.md 中删除「远程协作」章节
2. 删除该代理的远端凭据文件（workspace/data 和 admin_dir 均清理）

---

## 常见工作流

### 工作流 1：为受管代理开通安全远程对话（推荐）

先用 `agent_manager_cli.py` 创建代理（获得权限记录 + exec 白名单），再用 proxy 模式绑定。

**示例：** 本地代理 `vip-reader` 连接到远端实例 `moltbot-xxxx.sophnet.com` 上的 `memory_manager` agent：

```bash
cd "$SKILL_DIR" && uv run --project . python scripts/bot_client_setup.py setup \
  --agent-id "vip-reader" \
  --url "https://moltbot-xxxx.sophnet.com/bot-api/v2/memory_manager-api/chat" \
  --secret "remote_secret_abc123" \
  --remote-agent-id "memory_manager" \
  --mode proxy
```

其中：
- `vip-reader`：本地已创建的代理
- `moltbot-xxxx.sophnet.com`：远端 Sophnet 实例域名
- `memory_manager-api`：远端 Bot-API 的 account_id
- `remote_secret_abc123`：远端的 API Secret
- `memory_manager`：远端 agent ID

### 工作流 2：更换远端地址或密钥

直接重新运行 setup，会自动替换：

```bash
cd "$SKILL_DIR" && uv run --project . python scripts/bot_client_setup.py setup \
  --agent-id "vip-reader" \
  --url "https://moltbot-yyyy.sophnet.com/bot-api/v2/new-account-api/chat" \
  --secret "new_remote_secret_456" \
  --remote-agent-id "new_remote_agent" \
  --mode proxy
```

### 工作流 3：断开远程连接

```bash
cd "$SKILL_DIR" && uv run --project . python scripts/bot_client_setup.py remove \
  --agent-id "vip-reader"
```

---

## 输出格式

**所有命令输出 JSON 到 stdout。**

### 成功（setup）

```json
{
  "status": "ok",
  "action": "setup_bot_client",
  "agent_id": "vip-reader",
  "url": "https://moltbot-xxxx.sophnet.com/bot-api/v2/memory_manager-api/chat",
  "remote_agent_id": "memory_manager",
  "workspace": "/home/node/.openclaw/workspace-customer-agents/vip-reader",
  "credentials_file": "/home/node/.config/sophnet-customer-admin/vip-reader/bot_credentials.json"
}
```

### 成功（remove）

```json
{
  "status": "ok",
  "action": "remove_bot_client",
  "agent_id": "vip-reader",
  "removed_section": true,
  "removed_files": ["bot_credentials.json", "bot_session.txt"],
  "workspace": "/home/node/.openclaw/workspace-customer-agents/vip-reader"
}
```

### 失败

```json
{
  "status": "error",
  "action": "setup_bot_client",
  "message": "Workspace not found: ...",
  "fix": "请先使用 customer-agent create 创建代理"
}
```

---

## 安全说明

### proxy 模式（推荐）

- 凭据存储在 `/home/node/.config/sophnet-customer-admin/<agent-id>/`，对代理完全不可见
- AGENTS.md 仅包含 `bot_client_safe.sh` 调用模板，无 curl 命令、无凭据路径
- `bot_client_proxy.py` 在发送前检查 `permissions.json` 中的权限记录
- 请求 payload 中附带 `senderPermissions`，供服务端/接收方双重校验
- AGENTS.md 设为只读（chmod 444），防止代理篡改
- exec 白名单限制代理只能运行 `bot_client_safe.sh`

### raw 模式（旧模式）

- Secret 存储在 `data/bot_credentials.json`（代理可见）
- AGENTS.md 包含 curl 模板和凭据文件路径
- 权限仅靠 LLM 文本约束，无程序化强制

### 通用

- `--remote-agent-id` 必须填写为分发方 agent 的 ID，以确保权限链路正确传递

## 已知问题：Docker 环境下 .sh 脚本无执行权限

**现象：** 代理执行 `bot_client_safe.sh` 时报 `Permission denied`（exit code 126）。

**原因：** `clawhub` 在 gateway 启动后才安装 skill，`.sh` 脚本可能没有执行权限。

**已有的自动修复机制（无需手动操作）：**

1. `bot_client_setup.py setup` 在查找 `.sh` 脚本时会自动补上执行权限
2. `docker-entrypoint.sh` 后台每 15 秒检测并修复缺少执行权限的 `.sh` 文件（需使用最新版 entrypoint 重新构建镜像）

**如果仍遇到此问题（老镜像未重建）：**

```bash
# 在容器内手动执行
find /home/node/.openclaw/skills -name '*.sh' -exec chmod +x {} \;
```

## ⚠️ FORBIDDEN OPERATIONS

**Do NOT:**

- 直接编辑代理的 AGENTS.md（必须通过本脚本）
- 将 secret 明文写入 AGENTS.md 或其他非凭据文件中
- 在未创建代理的情况下执行 setup（必须先用 customer-agent create）
- 对需要权限约束的场景使用 raw 模式（应使用 proxy 模式）
