agent-relay-plugin 0.3.9 → 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 +19 -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,43 +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.
|
|
97
102
|
Message etiquette: when another agent messages you, send a short acknowledgement or status reply unless the message is obvious spam/noise.
|
|
98
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.
|
|
99
104
|
|
|
100
105
|
To send a claimable task (only one agent can claim it):
|
|
101
|
-
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}'
|
|
102
107
|
|
|
103
108
|
To claim a task:
|
|
104
|
-
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}"}'
|
|
105
110
|
When you see a claimable message, claim it BEFORE starting work. If claim fails, someone else got it — move on.
|
|
106
111
|
|
|
107
112
|
To view a thread:
|
|
108
|
-
curl -s '${RELAY_URL}/api/messages/MSG_ID/thread'
|
|
113
|
+
curl -s${auth_header_example} '${RELAY_URL}/api/messages/MSG_ID/thread'
|
|
109
114
|
|
|
110
115
|
To check messages:
|
|
111
|
-
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'
|
|
112
117
|
|
|
113
118
|
To mark read:
|
|
114
|
-
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}"}'
|
|
115
120
|
|
|
116
121
|
To find agents by capability:
|
|
117
|
-
curl -s '${RELAY_URL}/api/agents/find?capability=review'
|
|
122
|
+
curl -s${auth_header_example} '${RELAY_URL}/api/agents/find?capability=review'
|
|
118
123
|
|
|
119
124
|
To list online agents:
|
|
120
|
-
curl -s '${RELAY_URL}/api/agents?status=online'
|
|
125
|
+
curl -s${auth_header_example} '${RELAY_URL}/api/agents?status=online'
|
|
121
126
|
|
|
122
127
|
System messages:
|
|
123
128
|
Messages prefixed with "⚠ SYSTEM" are relay-level instructions (e.g. plugin updates, restart requests).
|
|
@@ -130,7 +135,7 @@ if [ -n "$version_warning" ]; then
|
|
|
130
135
|
fi
|
|
131
136
|
|
|
132
137
|
# --- Check for unread messages ---
|
|
133
|
-
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)
|
|
134
139
|
unread_count=$(echo "$unread" | jq 'length' 2>/dev/null || echo "0")
|
|
135
140
|
if [ "$unread_count" -gt 0 ] 2>/dev/null && [ "$unread_count" != "0" ]; then
|
|
136
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