agent-relay-plugin 0.3.8 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/hooks/poll-inbox.sh +9 -5
- package/hooks/relay-monitor.sh +21 -14
- package/hooks/session-end.sh +5 -1
- package/hooks/set-status.sh +5 -1
- package/package.json +1 -1
package/hooks/poll-inbox.sh
CHANGED
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
RELAY_URL="$1"
|
|
7
7
|
AGENT_ID="$2"
|
|
8
8
|
INTERVAL="${3:-10}"
|
|
9
|
+
auth_header_args=()
|
|
10
|
+
if [ -n "${AGENT_RELAY_TOKEN:-}" ]; then
|
|
11
|
+
auth_header_args=(-H "X-Agent-Relay-Token: ${AGENT_RELAY_TOKEN}")
|
|
12
|
+
fi
|
|
9
13
|
|
|
10
14
|
if [ -z "$RELAY_URL" ] || [ -z "$AGENT_ID" ]; then
|
|
11
15
|
echo "Usage: poll-inbox.sh <relay-url> <agent-id> [interval]" >&2
|
|
@@ -19,12 +23,12 @@ trap cleanup EXIT
|
|
|
19
23
|
echo $$ > "$pid_file"
|
|
20
24
|
|
|
21
25
|
# Bootstrap cursor at current max so we only see messages arriving after session start.
|
|
22
|
-
since_id=$(curl -s "${RELAY_URL}/api/messages/cursor" 2>/dev/null | jq -r '.latestId // 0' 2>/dev/null || echo 0)
|
|
26
|
+
since_id=$(curl -s "${auth_header_args[@]}" "${RELAY_URL}/api/messages/cursor" 2>/dev/null | jq -r '.latestId // 0' 2>/dev/null || echo 0)
|
|
23
27
|
|
|
24
28
|
fail_streak=0
|
|
25
29
|
marked_ready=false
|
|
26
30
|
while true; do
|
|
27
|
-
hb_code=$(curl -s -o /dev/null -w '%{http_code}' -X POST \
|
|
31
|
+
hb_code=$(curl -s -o /dev/null -w '%{http_code}' -X POST "${auth_header_args[@]}" \
|
|
28
32
|
"${RELAY_URL}/api/agents/${AGENT_ID}/heartbeat" 2>/dev/null)
|
|
29
33
|
|
|
30
34
|
# Agent was deleted or doesn't exist — we're orphaned, exit.
|
|
@@ -32,7 +36,7 @@ while true; do
|
|
|
32
36
|
exit 0
|
|
33
37
|
fi
|
|
34
38
|
|
|
35
|
-
msgs=$(curl -s --fail "${RELAY_URL}/api/messages?for=${AGENT_ID}&sinceId=${since_id}&unread=true" 2>/dev/null)
|
|
39
|
+
msgs=$(curl -s --fail "${auth_header_args[@]}" "${RELAY_URL}/api/messages?for=${AGENT_ID}&sinceId=${since_id}&unread=true" 2>/dev/null)
|
|
36
40
|
poll_rc=$?
|
|
37
41
|
|
|
38
42
|
if [ "$hb_code" != "200" ] || [ $poll_rc -ne 0 ]; then
|
|
@@ -52,7 +56,7 @@ while true; do
|
|
|
52
56
|
fail_streak=0
|
|
53
57
|
|
|
54
58
|
if [ "$marked_ready" = "false" ]; then
|
|
55
|
-
curl -s -o /dev/null -X PATCH "${RELAY_URL}/api/agents/${AGENT_ID}/ready" \
|
|
59
|
+
curl -s -o /dev/null -X PATCH "${RELAY_URL}/api/agents/${AGENT_ID}/ready" "${auth_header_args[@]}" \
|
|
56
60
|
-H 'Content-Type: application/json' -d '{"ready":true}' 2>/dev/null
|
|
57
61
|
marked_ready=true
|
|
58
62
|
fi
|
|
@@ -62,7 +66,7 @@ while true; do
|
|
|
62
66
|
echo "$msgs" | jq -r '.[] | if .type == "system" then "⚠ SYSTEM [msg:\(.id)]: \(.body)" else "[msg:\(.id)] \(.from) → \(.to) | \(.subject // "(no subject)"): \(.body)" end'
|
|
63
67
|
since_id=$(echo "$msgs" | jq '[.[].id] | max')
|
|
64
68
|
echo "$msgs" | jq -r '.[].id' | while read -r mid; do
|
|
65
|
-
curl -s -X PATCH "${RELAY_URL}/api/messages/${mid}" \
|
|
69
|
+
curl -s -X PATCH "${RELAY_URL}/api/messages/${mid}" "${auth_header_args[@]}" \
|
|
66
70
|
-H 'Content-Type: application/json' \
|
|
67
71
|
-d "{\"readBy\":\"${AGENT_ID}\"}" > /dev/null 2>&1 || true
|
|
68
72
|
done
|
package/hooks/relay-monitor.sh
CHANGED
|
@@ -6,6 +6,11 @@
|
|
|
6
6
|
|
|
7
7
|
RELAY_URL="${AGENT_RELAY_URL:-http://localhost:4850}"
|
|
8
8
|
PLUGIN_VERSION=$(jq -r '.version' "${CLAUDE_PLUGIN_ROOT}/.claude-plugin/plugin.json" 2>/dev/null || echo "unknown")
|
|
9
|
+
auth_header_args=()
|
|
10
|
+
auth_header_example=' ${AGENT_RELAY_TOKEN:+-H "X-Agent-Relay-Token: ${AGENT_RELAY_TOKEN}"}'
|
|
11
|
+
if [ -n "${AGENT_RELAY_TOKEN:-}" ]; then
|
|
12
|
+
auth_header_args=(-H "X-Agent-Relay-Token: ${AGENT_RELAY_TOKEN}")
|
|
13
|
+
fi
|
|
9
14
|
|
|
10
15
|
# --- Compute agent identity ---
|
|
11
16
|
machine=$(hostname)
|
|
@@ -39,7 +44,7 @@ if [ -f "$instance_state" ]; then
|
|
|
39
44
|
fi
|
|
40
45
|
rm -f "$old_pid_file"
|
|
41
46
|
fi
|
|
42
|
-
curl -s -o /dev/null -X PATCH "${RELAY_URL}/api/agents/${old_agent_id}/status" \
|
|
47
|
+
curl -s -o /dev/null -X PATCH "${RELAY_URL}/api/agents/${old_agent_id}/status" "${auth_header_args[@]}" \
|
|
43
48
|
-H 'Content-Type: application/json' -d '{"status":"offline"}' 2>/dev/null
|
|
44
49
|
fi
|
|
45
50
|
fi
|
|
@@ -49,7 +54,7 @@ printf '%s\n' "$agent_id" > "$instance_state"
|
|
|
49
54
|
caps_csv="${AGENT_RELAY_CAPS:-chat}"
|
|
50
55
|
caps_json=$(echo "$caps_csv" | jq -R 'split(",") | map(gsub("^\\s+|\\s+$"; ""))')
|
|
51
56
|
|
|
52
|
-
reg_code=$(curl -s -o /dev/null -w '%{http_code}' -X POST "${RELAY_URL}/api/agents" \
|
|
57
|
+
reg_code=$(curl -s -o /dev/null -w '%{http_code}' -X POST "${RELAY_URL}/api/agents" "${auth_header_args[@]}" \
|
|
53
58
|
-H 'Content-Type: application/json' \
|
|
54
59
|
-d "$(jq -n \
|
|
55
60
|
--arg id "$agent_id" \
|
|
@@ -67,7 +72,7 @@ if [ "$reg_code" != "201" ] && [ "$reg_code" != "200" ]; then
|
|
|
67
72
|
fi
|
|
68
73
|
|
|
69
74
|
# --- Check server version ---
|
|
70
|
-
server_version=$(curl -s "${RELAY_URL}/api/stats" 2>/dev/null | jq -r '.version // empty' 2>/dev/null)
|
|
75
|
+
server_version=$(curl -s "${auth_header_args[@]}" "${RELAY_URL}/api/stats" 2>/dev/null | jq -r '.version // empty' 2>/dev/null)
|
|
71
76
|
version_warning=""
|
|
72
77
|
if [ -z "$server_version" ]; then
|
|
73
78
|
version_warning="⚠ Server does not report its version — consider updating: bunx agent-relay-server@latest"
|
|
@@ -81,41 +86,43 @@ Agent Relay active. Your agent ID: ${agent_id}
|
|
|
81
86
|
Relay URL: ${RELAY_URL} | Server: ${server_version:-unknown} | Plugin: ${PLUGIN_VERSION}
|
|
82
87
|
|
|
83
88
|
To send a message:
|
|
84
|
-
curl -s -X POST ${RELAY_URL}/api/messages -H 'Content-Type: application/json' -d '{"from":"${agent_id}","to":"TARGET","body":"MESSAGE"}'
|
|
89
|
+
curl -s -X POST ${RELAY_URL}/api/messages${auth_header_example} -H 'Content-Type: application/json' -d '{"from":"${agent_id}","to":"TARGET","body":"MESSAGE"}'
|
|
85
90
|
TARGET: agent-id (direct), tag:NAME (by tag), cap:NAME (by capability), label:NAME (by human-set label, fan-out), broadcast (all)
|
|
86
91
|
|
|
87
92
|
To rename yourself (set a short, human-friendly label so the user can refer to you easily):
|
|
88
|
-
curl -s -X PATCH ${RELAY_URL}/api/agents/${agent_id}/label -H 'Content-Type: application/json' -d '{"label":"backend fixing"}'
|
|
93
|
+
curl -s -X PATCH ${RELAY_URL}/api/agents/${agent_id}/label${auth_header_example} -H 'Content-Type: application/json' -d '{"label":"backend fixing"}'
|
|
89
94
|
When the user tells you to rename yourself ("call yourself X", "rename to X"), call this endpoint.
|
|
90
95
|
Labels are NOT unique — if multiple sessions share a label, \`to: "label:X"\` fans out to all of them.
|
|
91
96
|
Use \`to: "label:backend fixing"\` when the user says "tell 'backend fixing' to do Y".
|
|
92
97
|
|
|
93
98
|
To reply to a message (threading):
|
|
94
|
-
curl -s -X POST ${RELAY_URL}/api/messages -H 'Content-Type: application/json' -d '{"from":"${agent_id}","to":"TARGET","body":"MESSAGE","replyTo":MSG_ID}'
|
|
99
|
+
curl -s -X POST ${RELAY_URL}/api/messages${auth_header_example} -H 'Content-Type: application/json' -d '{"from":"${agent_id}","to":"TARGET","body":"MESSAGE","replyTo":MSG_ID}'
|
|
95
100
|
Always use replyTo when responding to a specific message — it creates a thread.
|
|
96
101
|
The inbox monitor prefixes each message with [msg:ID] — parse the ID from there.
|
|
102
|
+
Message etiquette: when another agent messages you, send a short acknowledgement or status reply unless the message is obvious spam/noise.
|
|
103
|
+
Anti-loop rule: do not auto-reply to pure acknowledgements, "thanks", or "received" messages; acknowledge once, then only send follow-ups when there is new work, a decision, or a deliverable.
|
|
97
104
|
|
|
98
105
|
To send a claimable task (only one agent can claim it):
|
|
99
|
-
curl -s -X POST ${RELAY_URL}/api/messages -H 'Content-Type: application/json' -d '{"from":"${agent_id}","to":"cap:review","body":"TASK","claimable":true}'
|
|
106
|
+
curl -s -X POST ${RELAY_URL}/api/messages${auth_header_example} -H 'Content-Type: application/json' -d '{"from":"${agent_id}","to":"cap:review","body":"TASK","claimable":true}'
|
|
100
107
|
|
|
101
108
|
To claim a task:
|
|
102
|
-
curl -s -X POST ${RELAY_URL}/api/messages/MSG_ID/claim -H 'Content-Type: application/json' -d '{"agentId":"${agent_id}"}'
|
|
109
|
+
curl -s -X POST ${RELAY_URL}/api/messages/MSG_ID/claim${auth_header_example} -H 'Content-Type: application/json' -d '{"agentId":"${agent_id}"}'
|
|
103
110
|
When you see a claimable message, claim it BEFORE starting work. If claim fails, someone else got it — move on.
|
|
104
111
|
|
|
105
112
|
To view a thread:
|
|
106
|
-
curl -s '${RELAY_URL}/api/messages/MSG_ID/thread'
|
|
113
|
+
curl -s${auth_header_example} '${RELAY_URL}/api/messages/MSG_ID/thread'
|
|
107
114
|
|
|
108
115
|
To check messages:
|
|
109
|
-
curl -s '${RELAY_URL}/api/messages?for=${agent_id}&unread=true'
|
|
116
|
+
curl -s${auth_header_example} '${RELAY_URL}/api/messages?for=${agent_id}&unread=true'
|
|
110
117
|
|
|
111
118
|
To mark read:
|
|
112
|
-
curl -s -X PATCH ${RELAY_URL}/api/messages/ID -H 'Content-Type: application/json' -d '{"readBy":"${agent_id}"}'
|
|
119
|
+
curl -s -X PATCH ${RELAY_URL}/api/messages/ID${auth_header_example} -H 'Content-Type: application/json' -d '{"readBy":"${agent_id}"}'
|
|
113
120
|
|
|
114
121
|
To find agents by capability:
|
|
115
|
-
curl -s '${RELAY_URL}/api/agents/find?capability=review'
|
|
122
|
+
curl -s${auth_header_example} '${RELAY_URL}/api/agents/find?capability=review'
|
|
116
123
|
|
|
117
124
|
To list online agents:
|
|
118
|
-
curl -s '${RELAY_URL}/api/agents?status=online'
|
|
125
|
+
curl -s${auth_header_example} '${RELAY_URL}/api/agents?status=online'
|
|
119
126
|
|
|
120
127
|
System messages:
|
|
121
128
|
Messages prefixed with "⚠ SYSTEM" are relay-level instructions (e.g. plugin updates, restart requests).
|
|
@@ -128,7 +135,7 @@ if [ -n "$version_warning" ]; then
|
|
|
128
135
|
fi
|
|
129
136
|
|
|
130
137
|
# --- Check for unread messages ---
|
|
131
|
-
unread=$(curl -s "${RELAY_URL}/api/messages?for=${agent_id}&unread=true" 2>/dev/null)
|
|
138
|
+
unread=$(curl -s "${auth_header_args[@]}" "${RELAY_URL}/api/messages?for=${agent_id}&unread=true" 2>/dev/null)
|
|
132
139
|
unread_count=$(echo "$unread" | jq 'length' 2>/dev/null || echo "0")
|
|
133
140
|
if [ "$unread_count" -gt 0 ] 2>/dev/null && [ "$unread_count" != "0" ]; then
|
|
134
141
|
echo ""
|
package/hooks/session-end.sh
CHANGED
|
@@ -3,12 +3,16 @@
|
|
|
3
3
|
# Marks this session's agent as offline using state file written by relay-monitor.
|
|
4
4
|
|
|
5
5
|
RELAY_URL="${AGENT_RELAY_URL:-http://localhost:4850}"
|
|
6
|
+
auth_header_args=()
|
|
7
|
+
if [ -n "${AGENT_RELAY_TOKEN:-}" ]; then
|
|
8
|
+
auth_header_args=(-H "X-Agent-Relay-Token: ${AGENT_RELAY_TOKEN}")
|
|
9
|
+
fi
|
|
6
10
|
instance_state="/tmp/agent-relay-instance-${PPID}.state"
|
|
7
11
|
|
|
8
12
|
if [ -f "$instance_state" ]; then
|
|
9
13
|
agent_id=$(head -1 "$instance_state" 2>/dev/null)
|
|
10
14
|
if [ -n "$agent_id" ]; then
|
|
11
|
-
curl -s -X PATCH "${RELAY_URL}/api/agents/${agent_id}/status" \
|
|
15
|
+
curl -s -X PATCH "${RELAY_URL}/api/agents/${agent_id}/status" "${auth_header_args[@]}" \
|
|
12
16
|
-H 'Content-Type: application/json' \
|
|
13
17
|
-d '{"status":"offline"}' \
|
|
14
18
|
> /dev/null 2>&1 &
|
package/hooks/set-status.sh
CHANGED
|
@@ -9,6 +9,10 @@ case "$status" in
|
|
|
9
9
|
esac
|
|
10
10
|
|
|
11
11
|
RELAY_URL="${AGENT_RELAY_URL:-http://localhost:4850}"
|
|
12
|
+
auth_header_args=()
|
|
13
|
+
if [ -n "${AGENT_RELAY_TOKEN:-}" ]; then
|
|
14
|
+
auth_header_args=(-H "X-Agent-Relay-Token: ${AGENT_RELAY_TOKEN}")
|
|
15
|
+
fi
|
|
12
16
|
instance_state="/tmp/agent-relay-instance-${PPID}.state"
|
|
13
17
|
|
|
14
18
|
if [ ! -f "$instance_state" ]; then
|
|
@@ -20,7 +24,7 @@ if [ -z "$agent_id" ]; then
|
|
|
20
24
|
exit 0
|
|
21
25
|
fi
|
|
22
26
|
|
|
23
|
-
curl -s -o /dev/null -X PATCH "${RELAY_URL}/api/agents/${agent_id}/status" \
|
|
27
|
+
curl -s -o /dev/null -X PATCH "${RELAY_URL}/api/agents/${agent_id}/status" "${auth_header_args[@]}" \
|
|
24
28
|
-H 'Content-Type: application/json' \
|
|
25
29
|
-d "{\"status\":\"${status}\"}" \
|
|
26
30
|
2>/dev/null || true
|
package/package.json
CHANGED