Skill: lidian6864677/sub-agent-creator (version 1.0.1)

--- name: agent-creator description: "Full workflow for creating an OpenClaw Agent. Use when the user says 'create an agent', 'make a new agent', 'add a bot', or needs to set up a new AI assistant. Covers the complete setup process including (1) adding agent config and peer bindings to openclaw.json, (2) creating workspace directory with SOUL.md persona, (3) scaffolding required folders and files, (4) copying agent runtime configs from main, (5) restarting gateway to apply changes." --- # Agent Creator - OpenClaw Agent Setup Tool Automates the full end-to-end flow for creating an OpenClaw Agent. ## Trigger Phrases Activate when user says things like: - "Create an agent" - "Make a new bot" - "Set up a new agent" - "Add an AI assistant" ## Full Workflow ### Step 1: Gather Information Ask the user: 1. **Agent ID** (lowercase, hyphens only): e.g. `qisi`, `code-review`, `brainstorm` 2. **Agent Display Name**: e.g. "Brainstorm Buddy", "Code Reviewer" 3. **Purpose / Personality**: What does this agent do? What's its style? 4. **Group Chat Binding** (optional): peer.id of a group chat, e.g. `oc_xxx` (kind = group) 5. **Direct Chat Binding** (optional): peer.id of a user, e.g. `ou_xxx` (kind = direct) ### Step 2: Create Workspace Directory ```bash OPENCLAW_DIR=~/.openclaw mkdir -p $OPENCLAW_DIR/workspace-{agent_id} mkdir -p $OPENCLAW_DIR/workspace-{agent_id}/memory mkdir -p $OPENCLAW_DIR/workspace-{agent_id}/skills ``` ### Step 3: Write Workspace Files Create the following files in the workspace directory: - `SOUL.md` — Agent persona (see template below) - `USER.md` — User info template - `AGENTS.md` — Session bootstrap instructions - `HEARTBEAT.md` — Heartbeat config - `TOOLS.md` — Tool notes - `memory/` — Daily memory folder - `IDENTITY.md` — Agent identity definition (optional) - `BOOTSTRAP.md` — First-run bootstrap (optional) **AGENTS.md content** (copied from ~/.openclaw/workspace/AGENTS.md): ```markdown # AGENTS.md - Your Workspace If `BOOTSTRAP.md` exists, that's your birth certificate. Follow it, figure out who you are, then delete it. ## Every Session Before doing anything else: 1. Read `SOUL.md` — this is who you are 2. Read `USER.md` — this is who you're helping 3. Read `memory/YYYY-MM-DD.md` (today + yesterday) for recent context 4. **If in MAIN SESSION** (direct chat with your human): Also read `MEMORY.md` ## Memory You wake up fresh each session. These files are your continuity: - **Daily notes:** `memory/YYYY-MM-DD.md` — raw logs of what happened - **Long-term:** `MEMORY.md` — your curated memories ## Safety - Don't exfiltrate private data - When in doubt, ask. ``` **HEARTBEAT.md content**: ```markdown # HEARTBEAT.md # Keep this file empty to skip heartbeat API calls. ``` **TOOLS.md content**: ```markdown # TOOLS.md - Local Notes Notes specific to this agent's setup. ``` ### Step 4: Create Agent Runtime Directory ```bash OPENCLAW_DIR=~/.openclaw mkdir -p $OPENCLAW_DIR/agents/{agent_id}/agent mkdir -p $OPENCLAW_DIR/agents/{agent_id}/sessions ``` ### Step 5: Copy Agent Config from Main ```bash OPENCLAW_DIR=~/.openclaw cp $OPENCLAW_DIR/agents/main/agent/models.json $OPENCLAW_DIR/agents/{agent_id}/agent/ cp $OPENCLAW_DIR/agents/main/agent/auth-profiles.json $OPENCLAW_DIR/agents/{agent_id}/agent/ ``` If the main agent config files don't exist, warn the user and ask them to provide `models.json` and `auth-profiles.json` manually. ### Step 6: Update openclaw.json **Back up first:** ```bash cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.bak ``` Read the current config and add the new agent to `agents.list`: ```json { "id": "{agent_id}", "name": "{agent_name}", "workspace": "~/.openclaw/workspace-{agent_id}", "agentDir": "~/.openclaw/agents/{agent_id}/agent" } ``` Add bindings if provided. For group chat: ```json { "agentId": "{agent_id}", "match": { "channel": "feishu", "peer": { "kind": "group", "id": "{group_chat_id}" } } } ``` For direct chat: ```json { "agentId": "{agent_id}", "match": { "channel": "feishu", "peer": { "kind": "direct", "id": "{user_id}" } } } ``` ### Step 7: Install Skills (optional) If the agent needs specific skills: ```bash cp -r ~/.openclaw/skills/{skill-name} ~/.openclaw/workspace-{agent_id}/skills/ ``` ### Step 8: Restart Gateway ```bash openclaw gateway restart ``` ### Step 9: Verify & Report Tell the user: - Agent has been created successfully - How to interact with it (@ in group chat, or DM) - How to customize it further (edit SOUL.md, add skills, etc.) ## SOUL.md Template ```markdown # SOUL.md - {Agent Name} _{One-line purpose}_ ## Core Identity **You are "{Agent Name}"** — {detailed description} ## Principles - {principle 1} - {principle 2} - {principle 3} ## Style - {style description} --- _{Mission statement}_ ``` ## Final Directory Structure After creation, the layout should be: ``` ~/.openclaw/ ├── agents/ │ └── {agent_id}/ │ ├── agent/ │ │ ├── auth-profiles.json │ │ └── models.json │ └── sessions/ └── workspace-{agent_id}/ ├── AGENTS.md ├── BOOTSTRAP.md (optional) ├── HEARTBEAT.md ├── IDENTITY.md (optional) ├── SOUL.md ├── TOOLS.md ├── USER.md ├── memory/ └── skills/ (optional) ``` ## Important Notes - Workspace directory name should use the agent_id (English lowercase + hyphens), e.g. `workspace-brainstorm` - Agent ID must be lowercase alphanumeric with hyphens only - Group chat binding requires the bot to be manually added to the group (auto-join needs extra permissions) - Always back up `openclaw.json` before modifying - Always copy `models.json` and `auth-profiles.json` to the agents directory - Use the helper script `scripts/agent_creator.py` to automate the config and directory creation

path: scripts/agent_creator.py
content: #!/usr/bin/env python3
"""
OpenClaw Agent Creator - Helper Script
Automates directory creation, config update, and file scaffolding for new OpenClaw agents.
"""

import json
import os
import shutil
import subprocess
import sys
from pathlib import Path

OPENCLAW_DIR = Path.home() / ".openclaw"
OPENCLAW_JSON = OPENCLAW_DIR / "openclaw.json"
MAIN_AGENT_DIR = OPENCLAW_DIR / "agents" / "main" / "agent"


def load_config():
    if not OPENCLAW_JSON.exists():
        print(f"Error: {OPENCLAW_JSON} not found")
        sys.exit(1)
    with open(OPENCLAW_JSON, "r") as f:
        return json.load(f)


def save_config(config):
    # Back up before writing
    backup = OPENCLAW_JSON.with_suffix(".json.bak")
    shutil.copy2(OPENCLAW_JSON, backup)
    print(f"Backed up config to {backup}")

    with open(OPENCLAW_JSON, "w") as f:
        json.dump(config, f, indent=2, ensure_ascii=False)
    print(f"Saved config to {OPENCLAW_JSON}")


def write_file(path: Path, content: str):
    path.write_text(content, encoding="utf-8")
    print(f"  Created {path.name}")


def create_workspace(agent_id: str):
    """Create workspace directory with all required files."""
    workspace_dir = OPENCLAW_DIR / f"workspace-{agent_id}"
    workspace_dir.mkdir(parents=True, exist_ok=True)
    (workspace_dir / "memory").mkdir(exist_ok=True)
    (workspace_dir / "skills").mkdir(exist_ok=True)

    # AGENTS.md
    write_file(
        workspace_dir / "AGENTS.md",
        """# AGENTS.md - Your Workspace

If `BOOTSTRAP.md` exists, that's your birth certificate. Follow it, figure out who you are, then delete it.

## Every Session

Before doing anything else:

1. Read `SOUL.md` — this is who you are
2. Read `USER.md` — this is who you're helping
3. Read `memory/YYYY-MM-DD.md` (today + yesterday) for recent context
4. **If in MAIN SESSION** (direct chat with your human): Also read `MEMORY.md`

## Memory

You wake up fresh each session. These files are your continuity:

- **Daily notes:** `memory/YYYY-MM-DD.md` — raw logs of what happened
- **Long-term:** `MEMORY.md` — your curated memories

## Safety

- Don't exfiltrate private data
- When in doubt, ask.
""",
    )

    # HEARTBEAT.md
    write_file(
        workspace_dir / "HEARTBEAT.md",
        "# HEARTBEAT.md\n\n# Keep this file empty to skip heartbeat API calls.\n",
    )

    # TOOLS.md
    write_file(
        workspace_dir / "TOOLS.md",
        "# TOOLS.md - Local Notes\n\nNotes specific to this agent's setup.\n",
    )

    # USER.md (empty template)
    write_file(
        workspace_dir / "USER.md",
        "# USER.md\n\nInformation about the user this agent is helping.\n",
    )

    # SOUL.md placeholder — user should customize this
    write_file(
        workspace_dir / "SOUL.md",
        f"# SOUL.md - {agent_id}\n\n_Define this agent's persona here._\n",
    )

    print(f"Created workspace: {workspace_dir}")
    return workspace_dir


def create_agent_dir(agent_id: str):
    """Create agent runtime directory and copy configs from main."""
    agent_dir = OPENCLAW_DIR / "agents" / agent_id / "agent"
    sessions_dir = OPENCLAW_DIR / "agents" / agent_id / "sessions"
    agent_dir.mkdir(parents=True, exist_ok=True)
    sessions_dir.mkdir(parents=True, exist_ok=True)

    # Copy config files from main agent
    for filename in ("models.json", "auth-profiles.json"):
        src = MAIN_AGENT_DIR / filename
        dst = agent_dir / filename
        if src.exists():
            shutil.copy2(src, dst)
            print(f"  Copied {filename} from main agent")
        else:
            print(f"  Warning: {src} not found — you need to provide {filename} manually")

    print(f"Created agent dir: {agent_dir}")
    return agent_dir


def update_config(agent_id: str, agent_name: str, group_id: str = None, user_id: str = None):
    """Add agent entry and optional bindings to openclaw.json."""
    config = load_config()

    # Check for duplicates
    for agent in config.get("agents", {}).get("list", []):
        if agent["id"] == agent_id:
            print(f"Error: Agent '{agent_id}' already exists in config")
            return False

    # Add agent to list
    new_agent = {
        "id": agent_id,
        "name": agent_name,
        "workspace": str(OPENCLAW_DIR / f"workspace-{agent_id}"),
        "agentDir": str(OPENCLAW_DIR / "agents" / agent_id / "agent"),
    }

    if "agents" not in config:
        config["agents"] = {"list": []}
    if "list" not in config["agents"]:
        config["agents"]["list"] = []

    config["agents"]["list"].append(new_agent)
    print(f"Added agent: {agent_id}")

    # Add bindings
    if "bindings" not in config:
        config["bindings"] = []

    if group_id:
        binding = {
            "agentId": agent_id,
            "match": {
                "channel": "feishu",
                "peer": {"kind": "group", "id": group_id},
            },
        }
        config["bindings"].append(binding)
        print(f"Added group binding: {group_id}")

    if user_id:
        binding = {
            "agentId": agent_id,
            "match": {
                "channel": "feishu",
                "peer": {"kind": "direct", "id": user_id},
            },
        }
        config["bindings"].append(binding)
        print(f"Added direct binding: {user_id}")

    save_config(config)
    return True


def restart_gateway():
    """Restart the OpenClaw gateway."""
    print("\nRestarting gateway...")
    result = subprocess.run(["openclaw", "gateway", "restart"], capture_output=True, text=True)
    if result.returncode == 0:
        print("Gateway restarted successfully")
    else:
        print(f"Warning: Gateway restart failed (exit code {result.returncode})")
        if result.stderr:
            print(f"  stderr: {result.stderr.strip()}")
        print("  You may need to restart it manually: openclaw gateway restart")


def create_agent(agent_id: str, agent_name: str, group_id: str = None, user_id: str = None):
    """Full agent creation flow."""
    print(f"\n{'='*50}")
    print(f"Creating agent: {agent_id} ({agent_name})")
    print(f"{'='*50}\n")

    # 1. Create workspace with all files
    print("[1/4] Creating workspace...")
    create_workspace(agent_id)

    # 2. Create agent runtime dir + copy configs
    print("\n[2/4] Creating agent directory...")
    create_agent_dir(agent_id)

    # 3. Update openclaw.json
    print("\n[3/4] Updating config...")
    if not update_config(agent_id, agent_name, group_id, user_id):
        return False

    # 4. Restart gateway
    print("\n[4/4] Restarting gateway...")
    restart_gateway()

    print(f"\n{'='*50}")
    print(f"Agent '{agent_id}' created successfully!")
    print(f"  Workspace: ~/.openclaw/workspace-{agent_id}/")
    print(f"  Agent dir: ~/.openclaw/agents/{agent_id}/")
    print(f"\nNext steps:")
    print(f"  1. Edit ~/.openclaw/workspace-{agent_id}/SOUL.md to define the persona")
    print(f"  2. Add skills to ~/.openclaw/workspace-{agent_id}/skills/ if needed")
    if group_id:
        print(f"  3. Make sure the bot is added to the group chat")
    print(f"{'='*50}")
    return True


if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Usage: python3 agent_creator.py <agent_id> <agent_name> [--group oc_xxx] [--user ou_xxx]")
        print()
        print("Examples:")
        print("  python3 agent_creator.py brainstorm 'Brainstorm Buddy'")
        print("  python3 agent_creator.py reviewer 'Code Reviewer' --group oc_abc123")
        print("  python3 agent_creator.py assistant 'My Assistant' --user ou_xyz789")
        print("  python3 agent_creator.py helper 'Team Helper' --group oc_abc --user ou_xyz")
        sys.exit(1)

    agent_id = sys.argv[1]
    agent_name = sys.argv[2]
    group_id = None
    user_id = None

    # Parse optional flags
    args = sys.argv[3:]
    i = 0
    while i < len(args):
        if args[i] == "--group" and i + 1 < len(args):
            group_id = args[i + 1]
            i += 2
        elif args[i] == "--user" and i + 1 < len(args):
            user_id = args[i + 1]
            i += 2
        else:
            print(f"Unknown argument: {args[i]}")
            sys.exit(1)

    create_agent(agent_id, agent_name, group_id, user_id)


path: references/soul_templates.md
content: # SOUL.md Templates

Choose the right template based on the agent's purpose:

## 1. Brainstorm / Discussion Partner

```markdown
# SOUL.md - {Agent Name}

_Your thinking partner for wild ideas_

## Core Identity

**You are "{Agent Name}"** — an AI partner who explores ideas with the user, challenges assumptions, and pushes thinking further.

## Principles

- Lead discussions, don't just answer questions
- Encourage bold ideas, but also point out flaws honestly
- Debate sharpens thinking — engage, don't just agree
- Summarize each discussion into a concrete markdown doc

## Style

- Direct and opinionated
- Professional but not rigid
- Asks follow-up questions, challenges assumptions

---

_Turn wild ideas into reality, together_
```

## 2. Work Assistant

```markdown
# SOUL.md - {Agent Name}

_Your professional AI work assistant_

## Core Identity

**You are "{Agent Name}"** — a specialist focused on {domain}.

## Principles

- Results-oriented, solve problems efficiently
- Confirm requirements proactively to avoid wasted effort
- Break complex tasks into clear steps
- Report progress regularly

## Style

- Concise, professional, no fluff
- Raise issues early
- Prioritize quality and accuracy

---

_Get work done, efficiently_
```

## 3. Learning Mentor

```markdown
# SOUL.md - {Agent Name}

_A mentor on your learning journey_

## Core Identity

**You are "{Agent Name}"** — patiently guiding the user through learning {subject/skill}.

## Principles

- Explain in simple, accessible terms
- Encourage questions — no question is too basic
- Build knowledge step by step, don't rush
- Quiz periodically to reinforce learning

## Style

- Patient and warm
- Guides through discovery, not lecturing
- Values understanding over memorization

---

_Growing together, one step at a time_
```

## 4. Creative Brainstorming

```markdown
# SOUL.md - {Agent Name}

_A catalyst for creativity_

## Core Identity

**You are "{Agent Name}"** — helping users generate more creative ideas.

## Principles

- Never dismiss an idea
- Build on and extend what's there
- Cross-pollinate from different domains for inspiration
- Capture every spark of an idea

## Style

- Energetic and enthusiastic
- Free-flowing, divergent thinking
- Uses analogies and metaphors

---

_Unleash unlimited creativity_
```


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