@perkos/perkos-a2a 0.8.35 → 0.9.1
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 +99 -21
- package/dist/agent.d.ts +14 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +363 -0
- package/dist/agent.js.map +1 -0
- package/dist/agentic-actions.js +472 -0
- package/dist/agentic-actions.js.map +1 -0
- package/dist/chat-client.d.ts +77 -0
- package/dist/chat-client.d.ts.map +1 -0
- package/dist/chat-client.js +364 -0
- package/dist/chat-client.js.map +1 -0
- package/dist/chat-store.d.ts +87 -0
- package/dist/chat-store.d.ts.map +1 -0
- package/dist/chat-store.js +233 -0
- package/dist/chat-store.js.map +1 -0
- package/dist/chat-types.d.ts +166 -0
- package/dist/chat-types.d.ts.map +1 -0
- package/dist/chat-types.js +13 -0
- package/dist/chat-types.js.map +1 -0
- package/dist/hermes-cli.d.ts +30 -0
- package/dist/hermes-cli.d.ts.map +1 -0
- package/dist/hermes-cli.js +120 -0
- package/dist/hermes-cli.js.map +1 -0
- package/dist/hermes-plugin.d.ts +91 -0
- package/dist/hermes-plugin.d.ts.map +1 -0
- package/dist/hermes-plugin.js +196 -0
- package/dist/hermes-plugin.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1022 -26
- package/dist/index.js.map +4 -4
- package/dist/pairing.js +66 -0
- package/dist/pairing.js.map +1 -0
- package/dist/relay-client.js +222 -0
- package/dist/relay-client.js.map +1 -0
- package/dist/relay.js +274 -0
- package/dist/relay.js.map +1 -0
- package/dist/runtime-reply.js +137 -0
- package/dist/runtime-reply.js.map +1 -0
- package/dist/server.js +611 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +36 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -1
- package/dist/types.js.map +1 -1
- package/docs/chat-client.md +190 -0
- package/docs/demo-setup.md +273 -0
- package/openclaw.plugin.json +38 -1
- package/package.json +25 -21
- package/scripts/hermes/install.mjs +211 -0
package/README.md
CHANGED
|
@@ -2,6 +2,48 @@
|
|
|
2
2
|
|
|
3
3
|
Agent-to-Agent (A2A) protocol plugin for [OpenClaw](https://openclaw.ai). Enables secure multi-agent communication using Google's A2A protocol specification with enterprise-grade relay infrastructure for NAT traversal.
|
|
4
4
|
|
|
5
|
+
## How the agent connects
|
|
6
|
+
|
|
7
|
+
This package ships in three deployment modes — same wire protocol, different runtime targets.
|
|
8
|
+
|
|
9
|
+
```mermaid
|
|
10
|
+
flowchart TB
|
|
11
|
+
subgraph A2A[" @perkos/perkos-a2a "]
|
|
12
|
+
Plugin["📦 OpenClaw plugin<br/>src/index.ts<br/>(auto-loads via openclaw.plugin.json)"]
|
|
13
|
+
Bridge["🌉 Standalone bridge<br/>bin/agent.ts<br/>(perkos-a2a-agent)"]
|
|
14
|
+
ChatClient["💬 ChatClient<br/>+ JSONL store + history paginator<br/>(shared across modes)"]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
OpenClawRuntime["🦾 OpenClaw runtime<br/>(enqueueSystemEvent + tools)"]
|
|
18
|
+
HermesAPI["🤖 Hermes API server<br/>POST /v1/responses<br/>+ local /chat/reply listener"]
|
|
19
|
+
Custom["🛠 Custom LLM loop<br/>(any process)"]
|
|
20
|
+
|
|
21
|
+
Transport["transport.perkos.xyz/a2a<br/>A2A tasks + pairing"]
|
|
22
|
+
Chat["chat.perkos.xyz/chat<br/>conversations"]
|
|
23
|
+
Disk["~/.perkos/conversations/<br/>{convId}/messages.jsonl"]
|
|
24
|
+
|
|
25
|
+
Plugin -->|"runtime hook"| OpenClawRuntime
|
|
26
|
+
Bridge -->|"HTTP"| HermesAPI
|
|
27
|
+
Bridge -.->|"library use"| Custom
|
|
28
|
+
|
|
29
|
+
Plugin --> Transport
|
|
30
|
+
Plugin --> Chat
|
|
31
|
+
Bridge --> Transport
|
|
32
|
+
Bridge --> Chat
|
|
33
|
+
|
|
34
|
+
Plugin -.-> ChatClient
|
|
35
|
+
Bridge -.-> ChatClient
|
|
36
|
+
ChatClient --> Disk
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Three modes, one identity.** All three authenticate with the same `relayApiKey`
|
|
40
|
+
(issued by the PerkOS MiniApp via `/api/agents/launch`, stored in Firestore
|
|
41
|
+
`/agents/{name}`) and use it for both Transport and Chat:
|
|
42
|
+
|
|
43
|
+
- **OpenClaw plugin** — declared in `openclaw.plugin.json`, loads automatically; tools like `perkos_a2a_send`, `perkos_chat_reply`, `perkos_chat_history` become available to the LLM.
|
|
44
|
+
- **Hermes bridge** (`bin/agent.ts` → `perkos-a2a-agent`) — long-running Node process; multiplexes tasks + chat; opens `127.0.0.1:5060/chat/reply` so the Hermes side can POST replies back.
|
|
45
|
+
- **Custom** — import `ChatClient` directly, wire your own LLM loop.
|
|
46
|
+
|
|
5
47
|
## 🔒 Security First
|
|
6
48
|
|
|
7
49
|
**A2A communication MUST be secured.** Without authentication, anyone on your network can send tasks to your agent, potentially executing arbitrary commands.
|
|
@@ -92,7 +134,7 @@ curl -s -X POST http://localhost:5050/a2a/jsonrpc \
|
|
|
92
134
|
|
|
93
135
|
```bash
|
|
94
136
|
# 1. Install the plugin
|
|
95
|
-
openclaw plugins install @perkos/perkos-a2a
|
|
137
|
+
openclaw plugins install @perkos/perkos-a2a
|
|
96
138
|
|
|
97
139
|
# 2. Configure (see config section below)
|
|
98
140
|
|
|
@@ -122,7 +164,7 @@ pairing flow. Do not share one global relay key across production agents.
|
|
|
122
164
|
OpenClaw agents install `@perkos/perkos-a2a` as an OpenClaw plugin:
|
|
123
165
|
|
|
124
166
|
```bash
|
|
125
|
-
openclaw plugins install @perkos/perkos-a2a
|
|
167
|
+
openclaw plugins install @perkos/perkos-a2a
|
|
126
168
|
openclaw gateway restart
|
|
127
169
|
```
|
|
128
170
|
|
|
@@ -178,40 +220,76 @@ curl https://transport.perkos.xyz/api/agents/Alice/heartbeat
|
|
|
178
220
|
|
|
179
221
|
### Hermes agent
|
|
180
222
|
|
|
181
|
-
Hermes does **not** load OpenClaw plugins directly.
|
|
182
|
-
|
|
223
|
+
Hermes does **not** load OpenClaw plugins directly. PerkOS ships a
|
|
224
|
+
**Hermes-native plugin** with the same install ergonomics as the
|
|
225
|
+
OpenClaw plugin: one install command, then a supervised service.
|
|
183
226
|
|
|
184
|
-
|
|
227
|
+
#### Option A — one-shot service install (parity with `openclaw plugins install`)
|
|
185
228
|
|
|
186
229
|
```bash
|
|
187
|
-
npm install -g @perkos/perkos-a2a
|
|
230
|
+
npm install -g @perkos/perkos-a2a
|
|
231
|
+
|
|
232
|
+
# Generate + activate a systemd unit (Linux) or launchd plist (macOS):
|
|
233
|
+
npx -p @perkos/perkos-a2a install-hermes --write \
|
|
234
|
+
--agent-name Apollo \
|
|
235
|
+
--relay-url wss://transport.perkos.xyz/a2a \
|
|
236
|
+
--relay-key "$A2A_RELAY_API_KEY"
|
|
237
|
+
|
|
238
|
+
# Linux: sudo systemctl enable --now perkos-a2a-hermes
|
|
239
|
+
# macOS: launchctl load -w ~/Library/LaunchAgents/xyz.perkos.a2a-hermes.plist
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
The installer pre-flights the Hermes API for reachability before
|
|
243
|
+
emitting the unit. Use `--emit` instead of `--write` to print the
|
|
244
|
+
config to stdout for review/pipe-to-tee.
|
|
245
|
+
|
|
246
|
+
#### Option B — programmatic embed
|
|
247
|
+
|
|
248
|
+
Hosts that can `import()` ESM (Hermes plugin hosts, custom Node
|
|
249
|
+
runtimes) embed the bridge directly:
|
|
250
|
+
|
|
251
|
+
```ts
|
|
252
|
+
import { createHermesPlugin } from "@perkos/perkos-a2a/hermes";
|
|
253
|
+
|
|
254
|
+
const plugin = createHermesPlugin({
|
|
255
|
+
agentName: "Apollo",
|
|
256
|
+
port: 5060,
|
|
257
|
+
relay: {
|
|
258
|
+
url: "wss://transport.perkos.xyz/a2a",
|
|
259
|
+
apiKey: process.env.A2A_RELAY_API_KEY!,
|
|
260
|
+
},
|
|
261
|
+
hermes: { url: "http://127.0.0.1:8642", endpoint: "/v1/responses" },
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
await plugin.start();
|
|
188
265
|
```
|
|
189
266
|
|
|
190
|
-
|
|
267
|
+
`createHermesPlugin` returns a `{ start, stop, info }` lifecycle —
|
|
268
|
+
intentionally shaped like the OpenClaw `registerService` contract so
|
|
269
|
+
the two integrations feel identical to whoever ships them.
|
|
270
|
+
|
|
271
|
+
#### Option C — direct CLI (long-running, no supervisor)
|
|
191
272
|
|
|
192
273
|
```bash
|
|
274
|
+
npm install -g @perkos/perkos-a2a
|
|
193
275
|
perkos-a2a-agent pair \
|
|
194
276
|
--invite https://transport.perkos.xyz/pairing/invites/inv_... \
|
|
195
277
|
--agent-name Apollo \
|
|
196
278
|
--runtime hermes-api \
|
|
197
279
|
--capabilities chat,code,research,tasks:receive,messages:send
|
|
198
|
-
```
|
|
199
280
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
A2A_RUNTIME=hermes-api \
|
|
205
|
-
A2A_MODE=client-only \
|
|
206
|
-
A2A_RELAY_ENABLED=true \
|
|
207
|
-
A2A_RELAY_URL=wss://transport.perkos.xyz/a2a \
|
|
208
|
-
A2A_RELAY_API_KEY=<scoped-agent-relay-key> \
|
|
209
|
-
HERMES_API_URL=http://127.0.0.1:8642 \
|
|
210
|
-
HERMES_API_ENDPOINT=/v1/responses \
|
|
211
|
-
API_SERVER_KEY=<optional-hermes-api-key> \
|
|
212
|
-
perkos-a2a-agent
|
|
281
|
+
perkos-a2a-hermes \
|
|
282
|
+
--agent-name Apollo \
|
|
283
|
+
--relay-url wss://transport.perkos.xyz/a2a \
|
|
284
|
+
--relay-key "$A2A_RELAY_API_KEY"
|
|
213
285
|
```
|
|
214
286
|
|
|
287
|
+
`perkos-a2a-hermes` is a thin shim over `perkos-a2a-agent` that
|
|
288
|
+
presets `--runtime hermes-api` and reads Hermes config from the
|
|
289
|
+
common env var names (`HERMES_API_URL`, `HERMES_API_KEY`,
|
|
290
|
+
`HERMES_API_ENDPOINT`). For non-default workflows, drop down to
|
|
291
|
+
`perkos-a2a-agent --config a2a.config.json`.
|
|
292
|
+
|
|
215
293
|
Before connecting, validate the local Hermes API Server:
|
|
216
294
|
|
|
217
295
|
```bash
|
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Standalone PerkOS A2A bridge.
|
|
4
|
+
*
|
|
5
|
+
* This is for runtimes that do not load OpenClaw plugins directly, especially
|
|
6
|
+
* Hermes Workspace. It runs the same A2A HTTP/relay server and delivers inbound
|
|
7
|
+
* tasks into a local runtime over that runtime's native wake/send API.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* perkos-a2a-agent --config ./a2a.config.json
|
|
11
|
+
* A2A_AGENT_NAME=hermes A2A_RUNTIME=hermes-api HERMES_API_URL=http://127.0.0.1:8642 perkos-a2a-agent
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG"}
|
package/dist/agent.js
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Standalone PerkOS A2A bridge.
|
|
4
|
+
*
|
|
5
|
+
* This is for runtimes that do not load OpenClaw plugins directly, especially
|
|
6
|
+
* Hermes Workspace. It runs the same A2A HTTP/relay server and delivers inbound
|
|
7
|
+
* tasks into a local runtime over that runtime's native wake/send API.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* perkos-a2a-agent --config ./a2a.config.json
|
|
11
|
+
* A2A_AGENT_NAME=hermes A2A_RUNTIME=hermes-api HERMES_API_URL=http://127.0.0.1:8642 perkos-a2a-agent
|
|
12
|
+
*/
|
|
13
|
+
import { readFileSync } from "fs";
|
|
14
|
+
import { createHash, randomUUID } from "crypto";
|
|
15
|
+
import net from "net";
|
|
16
|
+
import { A2AServer } from "./server.js";
|
|
17
|
+
import { completeTaskWithReply, generateRuntimeReply } from "./runtime-reply.js";
|
|
18
|
+
import { tryHandleAgenticTask } from "./agentic-actions.js";
|
|
19
|
+
import { buildClaimRequest, claimPairingInvite, defaultPairingPath, loadOrCreateIdentity, savePairingProfile } from "./pairing.js";
|
|
20
|
+
function argValue(flag) {
|
|
21
|
+
const idx = process.argv.indexOf(flag);
|
|
22
|
+
if (idx === -1)
|
|
23
|
+
return undefined;
|
|
24
|
+
return process.argv[idx + 1];
|
|
25
|
+
}
|
|
26
|
+
function hasFlag(flag) {
|
|
27
|
+
return process.argv.includes(flag);
|
|
28
|
+
}
|
|
29
|
+
function printHelp() {
|
|
30
|
+
console.log(`PerkOS A2A standalone bridge
|
|
31
|
+
|
|
32
|
+
Usage:
|
|
33
|
+
perkos-a2a-agent --config ./a2a.config.json
|
|
34
|
+
perkos-a2a-agent --setup
|
|
35
|
+
perkos-a2a-agent pair --invite https://swarm.perkos.xyz/pairing/invites/inv_... --agent-name Apollo --runtime hermes
|
|
36
|
+
|
|
37
|
+
Config sources:
|
|
38
|
+
--config, -c, or A2A_CONFIG JSON config file
|
|
39
|
+
A2A_AGENT_NAME Unique agent identity, e.g. Apollo-Hermes-OSX
|
|
40
|
+
A2A_PORT Unique local A2A port, e.g. 5060
|
|
41
|
+
A2A_BIND_HOST 127.0.0.1 for same-host/local-only, 0.0.0.0 for containers
|
|
42
|
+
A2A_PUBLIC_URL Advertised base URL, e.g. http://127.0.0.1:5060
|
|
43
|
+
A2A_PEERS JSON map: {"Perkos-Claw-Tester":"http://127.0.0.1:5050"}
|
|
44
|
+
A2A_RELAY_ENABLED=true Enable relay fallback/discovery
|
|
45
|
+
A2A_RELAY_URL=wss://... Relay WebSocket URL
|
|
46
|
+
A2A_RUNTIME=hermes-api Runtime delivery target
|
|
47
|
+
HERMES_API_URL=http://127.0.0.1:8642
|
|
48
|
+
HERMES_API_ENDPOINT=/v1/responses
|
|
49
|
+
API_SERVER_KEY=<key>
|
|
50
|
+
|
|
51
|
+
Pairing:
|
|
52
|
+
pair Claim a system invitation and save local identity/credential
|
|
53
|
+
--invite Pairing invite URL ending in /pairing/invites/<inviteId>
|
|
54
|
+
--agent-name or A2A_AGENT_NAME Agent display/registry name
|
|
55
|
+
--runtime or A2A_RUNTIME Runtime kind: hermes-api, hermes, openclaw, custom
|
|
56
|
+
--capabilities Comma-separated capabilities/scopes to advertise
|
|
57
|
+
--public-url or A2A_PUBLIC_URL Optional direct A2A public URL
|
|
58
|
+
--pairing-store Optional credential file path; defaults to ~/.perkos/a2a/agents/<agent>.json
|
|
59
|
+
|
|
60
|
+
Same-host / same-IP rule:
|
|
61
|
+
IP address is transport only, not identity. If multiple agents share one macOS/LAN/public IP,
|
|
62
|
+
distinguish them by agentName + unique port. Prefer loopback peer URLs such as
|
|
63
|
+
http://127.0.0.1:<peer-port> for direct same-host routing; use relay by agentName as fallback.
|
|
64
|
+
`);
|
|
65
|
+
}
|
|
66
|
+
async function isPortAvailable(port, host) {
|
|
67
|
+
return new Promise((resolve) => {
|
|
68
|
+
const srv = net.createServer();
|
|
69
|
+
srv.once("error", () => resolve(false));
|
|
70
|
+
srv.listen(port, host, () => srv.close(() => resolve(true)));
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
async function printSetup(config) {
|
|
74
|
+
const bindHost = config.bindHost || "0.0.0.0";
|
|
75
|
+
const port = config.port || 5050;
|
|
76
|
+
const loopbackUrl = `http://127.0.0.1:${port}/a2a/jsonrpc`;
|
|
77
|
+
const bindCheckHost = bindHost === "0.0.0.0" ? "127.0.0.1" : bindHost;
|
|
78
|
+
const portAvailable = await isPortAvailable(port, bindCheckHost);
|
|
79
|
+
console.log("PerkOS A2A setup check");
|
|
80
|
+
console.log(`Agent: ${config.agentName}`);
|
|
81
|
+
console.log(`Runtime: ${config.runtime?.kind || "hermes"}`);
|
|
82
|
+
console.log(`Bind: ${bindHost}:${port}`);
|
|
83
|
+
console.log(`Port available: ${portAvailable ? "yes" : "NO - choose a unique A2A_PORT"}`);
|
|
84
|
+
console.log(`Advertised publicUrl: ${config.publicUrl || "(not set)"}`);
|
|
85
|
+
console.log(`Local same-host URL: ${loopbackUrl}`);
|
|
86
|
+
console.log(`Relay: ${config.relay?.enabled ? "enabled" : "disabled"}${config.relay?.url ? ` (${config.relay.url})` : ""}`);
|
|
87
|
+
console.log(`Peers: ${Object.keys(config.peers || {}).join(", ") || "(none configured)"}`);
|
|
88
|
+
console.log("");
|
|
89
|
+
console.log("Same-host / same-IP guidance:");
|
|
90
|
+
console.log("- Do not identify agents by shared LAN/public IP.");
|
|
91
|
+
console.log("- Each local agent needs a unique agentName and port.");
|
|
92
|
+
console.log("- Configure direct same-host peers as http://127.0.0.1:<peer-port>.");
|
|
93
|
+
console.log("- Use relay for fallback/discovery by agentName when direct peer port is unknown.");
|
|
94
|
+
console.log("");
|
|
95
|
+
console.log("Example Apollo -> Morpheus peer map:");
|
|
96
|
+
console.log(' A2A_PEERS=\'{"Perkos-Claw-Tester":"http://127.0.0.1:5050"}\'');
|
|
97
|
+
}
|
|
98
|
+
function splitCsv(value, fallback = []) {
|
|
99
|
+
return value?.split(",").map((item) => item.trim()).filter(Boolean) || fallback;
|
|
100
|
+
}
|
|
101
|
+
function redactSecret(value, visible = 4) {
|
|
102
|
+
if (!value)
|
|
103
|
+
return "(none)";
|
|
104
|
+
if (value.length <= visible * 2)
|
|
105
|
+
return "***";
|
|
106
|
+
return `${value.slice(0, visible)}…${value.slice(-visible)}`;
|
|
107
|
+
}
|
|
108
|
+
function secretFingerprint(value) {
|
|
109
|
+
if (!value)
|
|
110
|
+
return "(none)";
|
|
111
|
+
return createHash("sha256").update(value).digest("hex").slice(0, 12);
|
|
112
|
+
}
|
|
113
|
+
function shellQuote(value) {
|
|
114
|
+
return `'${value.replace(/'/g, `'\''`)}'`;
|
|
115
|
+
}
|
|
116
|
+
async function runPairCommand() {
|
|
117
|
+
const inviteUrl = argValue("--invite") || process.env.A2A_PAIRING_URL;
|
|
118
|
+
if (!inviteUrl)
|
|
119
|
+
throw new Error("Missing --invite or A2A_PAIRING_URL");
|
|
120
|
+
const agentName = argValue("--agent-name") || process.env.A2A_AGENT_NAME || "agent";
|
|
121
|
+
const runtime = argValue("--runtime") || process.env.A2A_RUNTIME || "hermes";
|
|
122
|
+
const publicUrl = argValue("--public-url") || process.env.A2A_PUBLIC_URL;
|
|
123
|
+
const storePath = argValue("--pairing-store") || process.env.A2A_PAIRING_STORE || defaultPairingPath(agentName);
|
|
124
|
+
const capabilities = splitCsv(argValue("--capabilities") || process.env.A2A_CAPABILITIES, ["chat", "tasks:receive", "messages:send"]);
|
|
125
|
+
const identity = loadOrCreateIdentity(agentName, storePath);
|
|
126
|
+
const request = buildClaimRequest({ identity, runtime, capabilities, publicUrl });
|
|
127
|
+
const result = await claimPairingInvite(inviteUrl, request);
|
|
128
|
+
savePairingProfile({ identity: { ...identity, agentId: result.credential?.agentId || identity.agentId }, credential: result.credential, lastPairing: result }, storePath);
|
|
129
|
+
console.log("PerkOS A2A pairing result");
|
|
130
|
+
console.log(`Status: ${result.status}`);
|
|
131
|
+
console.log(`Invite: ${result.inviteId}`);
|
|
132
|
+
console.log(`Request: ${result.requestId}`);
|
|
133
|
+
console.log(`Stored: ${storePath}`);
|
|
134
|
+
if (result.pollUrl)
|
|
135
|
+
console.log(`Poll URL: ${result.pollUrl}`);
|
|
136
|
+
if (result.claimToken)
|
|
137
|
+
console.log(`Claim token: ${result.claimToken}`);
|
|
138
|
+
if (result.credential) {
|
|
139
|
+
console.log(`Agent ID: ${result.credential.agentId}`);
|
|
140
|
+
console.log(`System: ${result.credential.system}`);
|
|
141
|
+
console.log(`Relay: ${result.credential.relayUrl}`);
|
|
142
|
+
console.log(`Scopes: ${result.credential.scopes.join(", ") || "(none)"}`);
|
|
143
|
+
console.log(`Relay credential: saved locally (fingerprint ${secretFingerprint(result.credential.relayApiKey)}, redacted ${redactSecret(result.credential.relayApiKey)})`);
|
|
144
|
+
console.log("");
|
|
145
|
+
console.log("Credential saved. Do not paste or log the relay API key.");
|
|
146
|
+
console.log("Run bridge after exporting the stored credential from your local profile, or set A2A_RELAY_API_KEY securely via your secrets manager.");
|
|
147
|
+
console.log("Example without secrets:");
|
|
148
|
+
console.log(`A2A_AGENT_NAME=${shellQuote(result.credential.agentName)} \
|
|
149
|
+
A2A_RELAY_ENABLED=true \
|
|
150
|
+
A2A_RELAY_URL=${shellQuote(result.credential.relayUrl)} \
|
|
151
|
+
A2A_RUNTIME=${shellQuote(runtime)} \
|
|
152
|
+
perkos-a2a-agent`);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
console.log(result.message || "Waiting for approval in the inviting PerkOS system.");
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function parseJsonEnv(name, fallback) {
|
|
159
|
+
const raw = process.env[name];
|
|
160
|
+
if (!raw)
|
|
161
|
+
return fallback;
|
|
162
|
+
try {
|
|
163
|
+
return JSON.parse(raw);
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
throw new Error(`${name} must be valid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function loadConfig() {
|
|
170
|
+
const configPath = argValue("--config") || argValue("-c") || process.env.A2A_CONFIG;
|
|
171
|
+
if (configPath) {
|
|
172
|
+
return JSON.parse(readFileSync(configPath, "utf8"));
|
|
173
|
+
}
|
|
174
|
+
const port = Number(process.env.A2A_PORT || "5050");
|
|
175
|
+
const relayEnabled = String(process.env.A2A_RELAY_ENABLED || "").toLowerCase() === "true";
|
|
176
|
+
return {
|
|
177
|
+
agentName: process.env.A2A_AGENT_NAME || "agent",
|
|
178
|
+
port,
|
|
179
|
+
bindHost: process.env.A2A_BIND_HOST || "0.0.0.0",
|
|
180
|
+
publicUrl: process.env.A2A_PUBLIC_URL,
|
|
181
|
+
mode: process.env.A2A_MODE || "auto",
|
|
182
|
+
skills: parseJsonEnv("A2A_SKILLS", []),
|
|
183
|
+
peers: parseJsonEnv("A2A_PEERS", {}),
|
|
184
|
+
peerAuth: parseJsonEnv("A2A_PEER_AUTH", {}),
|
|
185
|
+
auth: process.env.A2A_API_KEYS
|
|
186
|
+
? { requireApiKey: true, apiKeys: process.env.A2A_API_KEYS.split(",").map((v) => v.trim()).filter(Boolean) }
|
|
187
|
+
: undefined,
|
|
188
|
+
relay: relayEnabled || process.env.A2A_RELAY_URL
|
|
189
|
+
? {
|
|
190
|
+
enabled: relayEnabled || Boolean(process.env.A2A_RELAY_URL),
|
|
191
|
+
url: process.env.A2A_RELAY_URL || "",
|
|
192
|
+
apiKey: process.env.A2A_RELAY_API_KEY || "",
|
|
193
|
+
hubPort: process.env.A2A_RELAY_HUB_PORT ? Number(process.env.A2A_RELAY_HUB_PORT) : undefined,
|
|
194
|
+
hubApiKeys: process.env.A2A_RELAY_HUB_API_KEYS?.split(",").map((v) => v.trim()).filter(Boolean),
|
|
195
|
+
}
|
|
196
|
+
: undefined,
|
|
197
|
+
runtime: {
|
|
198
|
+
kind: process.env.A2A_RUNTIME || "hermes",
|
|
199
|
+
sessionKey: process.env.A2A_SESSION_KEY,
|
|
200
|
+
hermesUrl: process.env.HERMES_WORKSPACE_URL,
|
|
201
|
+
hermesToken: process.env.HERMES_WORKSPACE_TOKEN || process.env.HERMES_SESSION_TOKEN,
|
|
202
|
+
hermesEndpoint: process.env.HERMES_WORKSPACE_ENDPOINT,
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
function taskMarker(task) {
|
|
207
|
+
return `[A2A_RESULT:${task.id}]`;
|
|
208
|
+
}
|
|
209
|
+
function buildRuntimeMessage(task, text) {
|
|
210
|
+
const from = task.metadata?.fromAgent || "unknown";
|
|
211
|
+
const marker = taskMarker(task);
|
|
212
|
+
return [
|
|
213
|
+
marker,
|
|
214
|
+
`From: ${from}`,
|
|
215
|
+
`Task ID: ${task.id}`,
|
|
216
|
+
`Context ID: ${task.contextId}`,
|
|
217
|
+
"",
|
|
218
|
+
"Execute the following request and include the final answer in your assistant reply.",
|
|
219
|
+
`Your final answer must begin with exactly: ${marker}`,
|
|
220
|
+
"Return the useful final answer after that marker.",
|
|
221
|
+
"",
|
|
222
|
+
text,
|
|
223
|
+
].join("\n");
|
|
224
|
+
}
|
|
225
|
+
async function deliverToHermes(config, message) {
|
|
226
|
+
const runtime = config.runtime || {};
|
|
227
|
+
const baseUrl = (runtime.hermesUrl || process.env.HERMES_API_URL || process.env.HERMES_WORKSPACE_URL || "http://127.0.0.1:8642").replace(/\/+$/, "");
|
|
228
|
+
const endpoint = runtime.hermesEndpoint || process.env.HERMES_API_ENDPOINT || process.env.HERMES_WORKSPACE_ENDPOINT || "/v1/responses";
|
|
229
|
+
const sessionKey = runtime.sessionKey || process.env.HERMES_SESSION_ID || process.env.HERMES_SESSION_KEY || "a2a";
|
|
230
|
+
const token = runtime.hermesToken || process.env.API_SERVER_KEY || process.env.HERMES_API_KEY || process.env.HERMES_WORKSPACE_TOKEN || process.env.HERMES_SESSION_TOKEN;
|
|
231
|
+
const url = `${baseUrl}${endpoint.startsWith("/") ? endpoint : `/${endpoint}`}`;
|
|
232
|
+
const headers = {
|
|
233
|
+
"content-type": "application/json",
|
|
234
|
+
"x-hermes-session-id": sessionKey,
|
|
235
|
+
"x-hermes-session-key": sessionKey,
|
|
236
|
+
};
|
|
237
|
+
if (token)
|
|
238
|
+
headers.authorization = `Bearer ${token}`;
|
|
239
|
+
const normalizedEndpoint = endpoint.replace(/^\/?/, "/");
|
|
240
|
+
const body = normalizedEndpoint.startsWith("/v1/chat/completions")
|
|
241
|
+
? { model: process.env.HERMES_MODEL || "hermes-agent", messages: [{ role: "user", content: message }], stream: false }
|
|
242
|
+
: normalizedEndpoint.startsWith("/v1/runs")
|
|
243
|
+
? { input: message, session_id: sessionKey }
|
|
244
|
+
: normalizedEndpoint.startsWith("/v1/responses")
|
|
245
|
+
? { model: process.env.HERMES_MODEL || "hermes-agent", input: message, store: true }
|
|
246
|
+
: { sessionKey, message };
|
|
247
|
+
const response = await fetch(url, { method: "POST", headers, body: JSON.stringify(body) });
|
|
248
|
+
if (!response.ok) {
|
|
249
|
+
const text = await response.text().catch(() => "");
|
|
250
|
+
throw new Error(`Hermes API delivery failed (${response.status}) at ${url}: ${text || response.statusText}`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
async function main() {
|
|
254
|
+
if (hasFlag("--help") || hasFlag("-h")) {
|
|
255
|
+
printHelp();
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
if (process.argv[2] === "pair") {
|
|
259
|
+
await runPairCommand();
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const config = loadConfig();
|
|
263
|
+
if (hasFlag("--setup")) {
|
|
264
|
+
await printSetup(config);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
const logger = console;
|
|
268
|
+
const server = new A2AServer(config, logger);
|
|
269
|
+
server.setTaskResultHandler(async (task, text) => {
|
|
270
|
+
const runtimeKind = config.runtime?.kind || "hermes";
|
|
271
|
+
task.status = {
|
|
272
|
+
state: "working",
|
|
273
|
+
timestamp: new Date().toISOString(),
|
|
274
|
+
message: { role: "agent", parts: [{ kind: "text", text: `Task dispatched to ${runtimeKind} runtime.` }] },
|
|
275
|
+
};
|
|
276
|
+
const handledAgentically = await tryHandleAgenticTask({
|
|
277
|
+
selfName: config.agentName,
|
|
278
|
+
server,
|
|
279
|
+
task,
|
|
280
|
+
text,
|
|
281
|
+
logger,
|
|
282
|
+
runtimeResponder: (prompt, marker) => generateRuntimeReply(config, prompt, marker),
|
|
283
|
+
}).catch((err) => {
|
|
284
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
285
|
+
logger.error(`[perkos-a2a] Agentic task handler failed: ${msg}`);
|
|
286
|
+
return false;
|
|
287
|
+
});
|
|
288
|
+
if (handledAgentically)
|
|
289
|
+
return;
|
|
290
|
+
if ((runtimeKind === "hermes" || runtimeKind === "hermes-api")) {
|
|
291
|
+
try {
|
|
292
|
+
await deliverToHermes(config, buildRuntimeMessage(task, text));
|
|
293
|
+
server.recordRuntimeDelivery({
|
|
294
|
+
ok: true,
|
|
295
|
+
status: "delivered",
|
|
296
|
+
taskId: task.id,
|
|
297
|
+
runtimeKind,
|
|
298
|
+
detail: "Delivered to Hermes API Server.",
|
|
299
|
+
});
|
|
300
|
+
task.artifacts.push({
|
|
301
|
+
kind: "artifact",
|
|
302
|
+
artifactId: randomUUID(),
|
|
303
|
+
parts: [{ kind: "text", text: "Delivered to Hermes API Server." }],
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
catch (err) {
|
|
307
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
308
|
+
logger.warn(`[perkos-a2a] Hermes API delivery unavailable; completing via PerkOS LLM fallback: ${msg}`);
|
|
309
|
+
server.recordRuntimeDelivery({
|
|
310
|
+
ok: false,
|
|
311
|
+
status: "failed",
|
|
312
|
+
taskId: task.id,
|
|
313
|
+
runtimeKind,
|
|
314
|
+
detail: msg,
|
|
315
|
+
});
|
|
316
|
+
task.artifacts.push({
|
|
317
|
+
kind: "artifact",
|
|
318
|
+
artifactId: randomUUID(),
|
|
319
|
+
parts: [{ kind: "text", text: `Hermes API delivery unavailable; completed via PerkOS LLM fallback. ${msg}` }],
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
const finalText = await generateRuntimeReply(config, text, taskMarker(task));
|
|
323
|
+
completeTaskWithReply(task, finalText);
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
if (runtimeKind === "none") {
|
|
327
|
+
server.recordRuntimeDelivery({
|
|
328
|
+
ok: true,
|
|
329
|
+
status: "delivered",
|
|
330
|
+
taskId: task.id,
|
|
331
|
+
runtimeKind,
|
|
332
|
+
detail: "Runtime delivery disabled.",
|
|
333
|
+
});
|
|
334
|
+
task.artifacts.push({
|
|
335
|
+
kind: "artifact",
|
|
336
|
+
artifactId: randomUUID(),
|
|
337
|
+
parts: [{ kind: "text", text: "Runtime delivery disabled." }],
|
|
338
|
+
});
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
throw new Error(`Standalone runtime '${runtimeKind}' is not supported yet. Use OpenClaw plugin mode for OpenClaw delivery.`);
|
|
342
|
+
});
|
|
343
|
+
server.setTaskFailureHandler((task, errorText) => {
|
|
344
|
+
task.status = {
|
|
345
|
+
state: "failed",
|
|
346
|
+
timestamp: new Date().toISOString(),
|
|
347
|
+
message: { role: "agent", parts: [{ kind: "text", text: errorText }] },
|
|
348
|
+
};
|
|
349
|
+
});
|
|
350
|
+
await server.start();
|
|
351
|
+
logger.info(`[perkos-a2a] standalone bridge running for ${config.agentName} (${config.runtime?.kind || "hermes"})`);
|
|
352
|
+
const stop = () => {
|
|
353
|
+
logger.info("[perkos-a2a] standalone bridge shutting down");
|
|
354
|
+
process.exit(0);
|
|
355
|
+
};
|
|
356
|
+
process.on("SIGINT", stop);
|
|
357
|
+
process.on("SIGTERM", stop);
|
|
358
|
+
}
|
|
359
|
+
main().catch((err) => {
|
|
360
|
+
console.error(`[perkos-a2a] standalone bridge failed: ${err instanceof Error ? err.stack || err.message : String(err)}`);
|
|
361
|
+
process.exit(1);
|
|
362
|
+
});
|
|
363
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|