Add recruitment skill for onboarding new agents
This commit is contained in:
53
recruitment/SKILL.md
Normal file
53
recruitment/SKILL.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
name: recruitment
|
||||||
|
description: Onboard new agents into OpenClaw. Use when creating a new agent, adding an agent to the system, or setting up a new agent workspace. Triggers on requests like "new agent", "add agent", "create agent", "recruit agent", "onboard agent".
|
||||||
|
---
|
||||||
|
|
||||||
|
# Recruitment Skill
|
||||||
|
|
||||||
|
Onboard new agents into OpenClaw with binding configuration.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
new-agent --type openclaw --agent-id <agent-id> [--model <primary-model>]
|
||||||
|
|
||||||
|
new-agent --type contractor --contractor-provider <claude|gemini> --agent-id <agent-id>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
The `new-agent` script executes these steps:
|
||||||
|
|
||||||
|
1. **Register agent**:
|
||||||
|
- `openclaw`: runs `openclaw agents add {agent-id} --model {primary-model} --workspace ~/.openclaw/workspace/workspace-{agent-id} --non-interactive`
|
||||||
|
- `contractor`: requires `contractor-agent` plugin; runs `openclaw contractor-agents add --agent-id {agent-id} --workspace ~/.openclaw/workspace/workspace-{agent-id} --contractor {contractor-provider}`
|
||||||
|
|
||||||
|
2. **Wait for bindings**:
|
||||||
|
- Poll `openclaw config get bindings` every 10s until `interviewee` accountId is no longer present
|
||||||
|
- Check `~/.openclaw/states/bindings.lock` exists → wait every 10s until it disappears
|
||||||
|
|
||||||
|
3. **Set bindings**:
|
||||||
|
- Create `~/.openclaw/states/bindings.lock`
|
||||||
|
- Fetch current bindings, append entry:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"agentId": "{agent-id}",
|
||||||
|
"match": {
|
||||||
|
"channel": "discord",
|
||||||
|
"accountId": "interviewee"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- Write back with `openclaw config set`
|
||||||
|
- Delete `bindings.lock`
|
||||||
|
|
||||||
|
4. **Configure interviewee account**:
|
||||||
|
```bash
|
||||||
|
openclaw config set channels.discord.accounts.interviewee {
|
||||||
|
"enabled": true,
|
||||||
|
"token": "<secret-mgr get-secret --key interviewee-discord-token>",
|
||||||
|
"groupPolicy": "open",
|
||||||
|
"streaming": { "mode": "off" }
|
||||||
|
}
|
||||||
|
```
|
||||||
122
recruitment/scripts/new-agent
Executable file
122
recruitment/scripts/new-agent
Executable file
@@ -0,0 +1,122 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
TYPE=""
|
||||||
|
AGENT_ID=""
|
||||||
|
MODEL=""
|
||||||
|
CONTRACTOR_PROVIDER=""
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: new-agent --type <openclaw|contractor> --agent-id <agent-id> [--model <primary-model>] [--contractor-provider <claude|gemini>]"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
--type)
|
||||||
|
TYPE="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--agent-id)
|
||||||
|
AGENT_ID="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--model)
|
||||||
|
MODEL="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--contractor-provider)
|
||||||
|
CONTRACTOR_PROVIDER="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -z "$TYPE" ]] || [[ -z "$AGENT_ID" ]]; then
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
WORKSPACE_DIR="$HOME/.openclaw/workspace/workspace-$AGENT_ID"
|
||||||
|
STATE_DIR="$HOME/.openclaw/states"
|
||||||
|
BINDINGS_LOCK="$STATE_DIR/bindings.lock"
|
||||||
|
|
||||||
|
# Step 1: Register agent
|
||||||
|
if [[ "$TYPE" == "openclaw" ]]; then
|
||||||
|
MODEL_ARG=""
|
||||||
|
if [[ -n "$MODEL" ]]; then
|
||||||
|
MODEL_ARG="--model $MODEL"
|
||||||
|
fi
|
||||||
|
openclaw agents add "$AGENT_ID" $MODEL_ARG --workspace "$WORKSPACE_DIR" --non-interactive
|
||||||
|
elif [[ "$TYPE" == "contractor" ]]; then
|
||||||
|
# Check contractor-agent plugin
|
||||||
|
if ! openclaw plugins list 2>/dev/null | grep -q "contractor-agent"; then
|
||||||
|
echo "Error: contractor-agent plugin is not installed" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
openclaw contractor-agents add --agent-id "$AGENT_ID" --workspace "$WORKSPACE_DIR" --contractor "$CONTRACTOR_PROVIDER"
|
||||||
|
else
|
||||||
|
echo "Error: unknown type '$TYPE'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Step 2: Wait for bindings
|
||||||
|
echo "Checking bindings..."
|
||||||
|
|
||||||
|
wait_for_bindings() {
|
||||||
|
local bindings
|
||||||
|
bindings=$(openclaw config get bindings 2>/dev/null || echo "{}")
|
||||||
|
if echo "$bindings" | grep -q '"interviewee"'; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_lock() {
|
||||||
|
if [[ -f "$BINDINGS_LOCK" ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
while wait_for_bindings; do
|
||||||
|
echo "another interview is ongoing, waiting..."
|
||||||
|
sleep 10
|
||||||
|
done
|
||||||
|
|
||||||
|
while wait_for_lock; do
|
||||||
|
echo "bindings locked, waiting..."
|
||||||
|
sleep 10
|
||||||
|
done
|
||||||
|
|
||||||
|
# Step 3: Set bindings
|
||||||
|
mkdir -p "$STATE_DIR"
|
||||||
|
touch "$BINDINGS_LOCK"
|
||||||
|
|
||||||
|
CURRENT_BINDINGS=$(openclaw config get bindings 2>/dev/null || echo "{}")
|
||||||
|
|
||||||
|
NEW_ENTRY="{\"agentId\": \"$AGENT_ID\", \"match\": {\"channel\": \"discord\", \"accountId\": \"interviewee\"}}"
|
||||||
|
|
||||||
|
if [[ "$CURRENT_BINDINGS" == "{}" ]] || [[ -z "$CURRENT_BINDINGS" ]]; then
|
||||||
|
NEW_BINDINGS="[$NEW_ENTRY]"
|
||||||
|
else
|
||||||
|
NEW_BINDINGS=$(echo "$CURRENT_BINDINGS" | sed 's/\(\[.*\)\]/\1,/' | sed 's/\]$//' | sed 's/\([{,]\)$/\1/')" $NEW_ENTRY]"
|
||||||
|
fi
|
||||||
|
|
||||||
|
openclaw config set bindings "$NEW_BINDINGS"
|
||||||
|
|
||||||
|
rm -f "$BINDINGS_LOCK"
|
||||||
|
|
||||||
|
# Step 4: Configure interviewee account
|
||||||
|
TOKEN=$(secret-mgr get-secret --key interviewee-discord-token 2>/dev/null || echo "")
|
||||||
|
|
||||||
|
if [[ -z "$TOKEN" ]]; then
|
||||||
|
echo "Error: failed to get interviewee-discord-token from secret-mgr" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
openclaw config set channels.discord.accounts.interviewee "{\"enabled\": true, \"token\": \"$TOKEN\", \"groupPolicy\": \"open\", \"streaming\": {\"mode\": \"off\"}}"
|
||||||
|
|
||||||
|
echo "Agent $AGENT_ID recruited successfully."
|
||||||
Reference in New Issue
Block a user