agent-relay-server 0.3.11 → 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/README.md +237 -22
- package/bin/agent-relay-codex.ts +79 -6
- package/codex/README.md +18 -3
- package/codex/hooks/session-start.ts +2 -2
- package/codex/live-sidecar.ts +2 -0
- package/codex/plugin/.codex-plugin/plugin.json +1 -1
- package/codex/plugin/skills/agent-relay/SKILL.md +1 -0
- package/codex/relay.ts +8 -3
- package/examples/integrations/github-issue.ts +54 -0
- package/examples/integrations/ops-alert.sh +27 -0
- package/examples/integrations/prometheus-alertmanager.ts +61 -0
- package/examples/integrations/support-ticket.sh +28 -0
- package/package.json +5 -4
- package/public/dashboard.js +701 -0
- package/public/index.html +143 -504
- package/src/cli.ts +217 -0
- package/src/config.ts +38 -0
- package/src/daemon.ts +453 -0
- package/src/db.ts +442 -16
- package/src/index.ts +96 -70
- package/src/routes.ts +334 -17
- package/src/security.ts +103 -0
- package/src/setup.ts +187 -0
- package/src/sse.ts +18 -2
- package/src/types.ts +67 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
type GitHubIssuePayload = {
|
|
4
|
+
action?: string;
|
|
5
|
+
issue?: {
|
|
6
|
+
number: number;
|
|
7
|
+
title: string;
|
|
8
|
+
body?: string;
|
|
9
|
+
html_url?: string;
|
|
10
|
+
labels?: Array<{ name: string }>;
|
|
11
|
+
};
|
|
12
|
+
repository?: {
|
|
13
|
+
full_name?: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const relayUrl = process.env.AGENT_RELAY_URL || "http://127.0.0.1:4850";
|
|
18
|
+
const token = process.env.AGENT_RELAY_INTEGRATION_TOKEN;
|
|
19
|
+
if (!token) throw new Error("AGENT_RELAY_INTEGRATION_TOKEN is required");
|
|
20
|
+
|
|
21
|
+
const target = process.env.AGENT_RELAY_TARGET || "cap:triage";
|
|
22
|
+
const channel = process.env.AGENT_RELAY_CHANNEL || "support";
|
|
23
|
+
const payload = JSON.parse(await Bun.stdin.text()) as GitHubIssuePayload;
|
|
24
|
+
const issue = payload.issue;
|
|
25
|
+
const repo = payload.repository?.full_name || "unknown/repo";
|
|
26
|
+
const action = payload.action || "unknown";
|
|
27
|
+
|
|
28
|
+
if (!issue || !["opened", "reopened", "labeled", "edited"].includes(action)) {
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const labels = issue.labels?.map((label) => label.name) ?? [];
|
|
33
|
+
const response = await fetch(new URL("/api/integrations/events", relayUrl), {
|
|
34
|
+
method: "POST",
|
|
35
|
+
headers: {
|
|
36
|
+
Authorization: `Bearer ${token}`,
|
|
37
|
+
"Content-Type": "application/json",
|
|
38
|
+
},
|
|
39
|
+
body: JSON.stringify({
|
|
40
|
+
type: "github-issue",
|
|
41
|
+
severity: labels.includes("P0") || labels.includes("critical") ? "critical" : labels.includes("P1") ? "warning" : "info",
|
|
42
|
+
dedupeKey: `github:${repo}:issue:${issue.number}`,
|
|
43
|
+
title: `${repo}#${issue.number}: ${issue.title}`,
|
|
44
|
+
body: issue.body || "(no issue body)",
|
|
45
|
+
target,
|
|
46
|
+
channel,
|
|
47
|
+
externalUrl: issue.html_url,
|
|
48
|
+
metadata: { repo, issueNumber: issue.number, action, labels },
|
|
49
|
+
}),
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
if (!response.ok) {
|
|
53
|
+
throw new Error(`failed to send GitHub issue ${repo}#${issue.number}: ${response.status} ${await response.text()}`);
|
|
54
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
: "${AGENT_RELAY_URL:=http://127.0.0.1:4850}"
|
|
5
|
+
: "${AGENT_RELAY_INTEGRATION_TOKEN:?set an integration token}"
|
|
6
|
+
|
|
7
|
+
service="${1:-prod-api}"
|
|
8
|
+
severity="${2:-critical}"
|
|
9
|
+
body="${3:-5xx rate is above threshold}"
|
|
10
|
+
|
|
11
|
+
curl -sS -X POST "${AGENT_RELAY_URL}/api/integrations/events" \
|
|
12
|
+
-H "Authorization: Bearer ${AGENT_RELAY_INTEGRATION_TOKEN}" \
|
|
13
|
+
-H "Content-Type: application/json" \
|
|
14
|
+
-d "$(jq -n \
|
|
15
|
+
--arg service "$service" \
|
|
16
|
+
--arg severity "$severity" \
|
|
17
|
+
--arg body "$body" \
|
|
18
|
+
'{
|
|
19
|
+
type: "alarm",
|
|
20
|
+
severity: $severity,
|
|
21
|
+
dedupeKey: ("ops:" + $service + ":alarm"),
|
|
22
|
+
title: ($service + " alarm"),
|
|
23
|
+
body: $body,
|
|
24
|
+
target: "cap:ops",
|
|
25
|
+
channel: "alerts",
|
|
26
|
+
metadata: { service: $service }
|
|
27
|
+
}')"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
type Alert = {
|
|
4
|
+
status?: string;
|
|
5
|
+
labels?: Record<string, string>;
|
|
6
|
+
annotations?: Record<string, string>;
|
|
7
|
+
fingerprint?: string;
|
|
8
|
+
generatorURL?: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type AlertmanagerPayload = {
|
|
12
|
+
status?: string;
|
|
13
|
+
alerts?: Alert[];
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const relayUrl = process.env.AGENT_RELAY_URL || "http://127.0.0.1:4850";
|
|
17
|
+
const token = process.env.AGENT_RELAY_INTEGRATION_TOKEN;
|
|
18
|
+
if (!token) throw new Error("AGENT_RELAY_INTEGRATION_TOKEN is required");
|
|
19
|
+
|
|
20
|
+
const target = process.env.AGENT_RELAY_TARGET || "cap:ops";
|
|
21
|
+
const channel = process.env.AGENT_RELAY_CHANNEL || "alerts";
|
|
22
|
+
const payload = JSON.parse(await Bun.stdin.text()) as AlertmanagerPayload;
|
|
23
|
+
const alerts = payload.alerts ?? [];
|
|
24
|
+
|
|
25
|
+
for (const alert of alerts) {
|
|
26
|
+
const labels = alert.labels ?? {};
|
|
27
|
+
const annotations = alert.annotations ?? {};
|
|
28
|
+
const name = labels.alertname || "Alertmanager alert";
|
|
29
|
+
const service = labels.service || labels.job || labels.instance || "unknown";
|
|
30
|
+
const status = alert.status === "resolved" || payload.status === "resolved" ? "resolved" : undefined;
|
|
31
|
+
|
|
32
|
+
const response = await fetch(new URL("/api/integrations/events", relayUrl), {
|
|
33
|
+
method: "POST",
|
|
34
|
+
headers: {
|
|
35
|
+
Authorization: `Bearer ${token}`,
|
|
36
|
+
"Content-Type": "application/json",
|
|
37
|
+
},
|
|
38
|
+
body: JSON.stringify({
|
|
39
|
+
type: "alertmanager",
|
|
40
|
+
severity: alertSeverity(labels.severity),
|
|
41
|
+
status,
|
|
42
|
+
dedupeKey: `alertmanager:${alert.fingerprint || name}:${service}`,
|
|
43
|
+
title: `${name} (${service})`,
|
|
44
|
+
body: annotations.description || annotations.summary || JSON.stringify(labels),
|
|
45
|
+
target,
|
|
46
|
+
channel,
|
|
47
|
+
externalUrl: alert.generatorURL,
|
|
48
|
+
metadata: { labels, annotations, alertStatus: alert.status },
|
|
49
|
+
}),
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
if (!response.ok) {
|
|
53
|
+
throw new Error(`failed to send alert ${name}: ${response.status} ${await response.text()}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function alertSeverity(value?: string): "info" | "warning" | "critical" {
|
|
58
|
+
if (value === "critical" || value === "page") return "critical";
|
|
59
|
+
if (value === "warning" || value === "warn") return "warning";
|
|
60
|
+
return "info";
|
|
61
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
: "${AGENT_RELAY_URL:=http://127.0.0.1:4850}"
|
|
5
|
+
: "${AGENT_RELAY_INTEGRATION_TOKEN:?set an integration token}"
|
|
6
|
+
|
|
7
|
+
ticket_id="${1:?ticket id}"
|
|
8
|
+
title="${2:?title}"
|
|
9
|
+
body="${3:?body}"
|
|
10
|
+
|
|
11
|
+
curl -sS -X POST "${AGENT_RELAY_URL}/api/integrations/events" \
|
|
12
|
+
-H "Authorization: Bearer ${AGENT_RELAY_INTEGRATION_TOKEN}" \
|
|
13
|
+
-H "Content-Type: application/json" \
|
|
14
|
+
-d "$(jq -n \
|
|
15
|
+
--arg ticket_id "$ticket_id" \
|
|
16
|
+
--arg title "$title" \
|
|
17
|
+
--arg body "$body" \
|
|
18
|
+
'{
|
|
19
|
+
type: "ticket",
|
|
20
|
+
severity: "warning",
|
|
21
|
+
dedupeKey: ("support:" + $ticket_id),
|
|
22
|
+
title: $title,
|
|
23
|
+
body: $body,
|
|
24
|
+
target: "cap:support",
|
|
25
|
+
channel: "support",
|
|
26
|
+
externalUrl: ("https://support.example/tickets/" + $ticket_id),
|
|
27
|
+
metadata: { ticketId: $ticket_id }
|
|
28
|
+
}')"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-relay-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Lightweight HTTP message relay for inter-agent communication across machines",
|
|
5
5
|
"module": "src/index.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -17,12 +17,15 @@
|
|
|
17
17
|
"codex/**/*.sh",
|
|
18
18
|
"codex/**/*.ps1",
|
|
19
19
|
"codex/plugin/**",
|
|
20
|
+
"examples/**",
|
|
20
21
|
"public/**",
|
|
21
22
|
"README.md"
|
|
22
23
|
],
|
|
23
24
|
"scripts": {
|
|
24
25
|
"start": "bun run src/index.ts",
|
|
25
26
|
"dev": "bun --watch run src/index.ts",
|
|
27
|
+
"test": "bun test",
|
|
28
|
+
"typecheck": "tsc --noEmit",
|
|
26
29
|
"codex:live": "bun run codex/live-sidecar.ts",
|
|
27
30
|
"codex:live:start": "bash codex/start-live.sh",
|
|
28
31
|
"codex:install": "bun run bin/agent-relay-codex.ts install",
|
|
@@ -45,9 +48,7 @@
|
|
|
45
48
|
"license": "MIT",
|
|
46
49
|
"author": "Edin Mujkanovic",
|
|
47
50
|
"devDependencies": {
|
|
48
|
-
"@types/bun": "latest"
|
|
49
|
-
},
|
|
50
|
-
"peerDependencies": {
|
|
51
|
+
"@types/bun": "latest",
|
|
51
52
|
"typescript": "^5"
|
|
52
53
|
},
|
|
53
54
|
"engines": {
|