@perkos/perkos-a2a 0.8.34 → 0.9.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 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.
@@ -106,6 +148,159 @@ openclaw perkos-a2a setup
106
148
  openclaw perkos-a2a status
107
149
  ```
108
150
 
151
+ ## Connect to PerkOS Transport
152
+
153
+ Production PerkOS mesh traffic uses the shared relay endpoint:
154
+
155
+ ```txt
156
+ wss://transport.perkos.xyz/a2a
157
+ ```
158
+
159
+ Agents should connect with a **scoped relay credential** issued by the PerkOS
160
+ pairing flow. Do not share one global relay key across production agents.
161
+
162
+ ### OpenClaw agent
163
+
164
+ OpenClaw agents install `@perkos/perkos-a2a` as an OpenClaw plugin:
165
+
166
+ ```bash
167
+ openclaw plugins install @perkos/perkos-a2a
168
+ openclaw gateway restart
169
+ ```
170
+
171
+ Then claim the PerkOS invite printed by the transport onboarding flow:
172
+
173
+ ```bash
174
+ perkos-a2a-agent pair \
175
+ --invite https://transport.perkos.xyz/pairing/invites/inv_... \
176
+ --agent-name Alice \
177
+ --runtime openclaw \
178
+ --capabilities chat,code,research,tasks:receive,messages:send
179
+ ```
180
+
181
+ Configure the plugin with the issued relay credential:
182
+
183
+ ```json
184
+ {
185
+ "plugins": {
186
+ "entries": {
187
+ "perkos-a2a": {
188
+ "enabled": true,
189
+ "config": {
190
+ "agentName": "Alice",
191
+ "mode": "client-only",
192
+ "relay": {
193
+ "enabled": true,
194
+ "url": "wss://transport.perkos.xyz/a2a",
195
+ "apiKey": "<scoped-agent-relay-key>"
196
+ },
197
+ "runtime": {
198
+ "kind": "openclaw",
199
+ "sessionKey": "agent:main"
200
+ }
201
+ }
202
+ }
203
+ }
204
+ }
205
+ }
206
+ ```
207
+
208
+ Restart OpenClaw and verify relay connectivity:
209
+
210
+ ```bash
211
+ openclaw gateway restart
212
+ openclaw perkos-a2a status
213
+ ```
214
+
215
+ The transport service can also verify onboarding from the server side:
216
+
217
+ ```bash
218
+ curl https://transport.perkos.xyz/api/agents/Alice/heartbeat
219
+ ```
220
+
221
+ ### Hermes agent
222
+
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.
226
+
227
+ #### Option A — one-shot service install (parity with `openclaw plugins install`)
228
+
229
+ ```bash
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();
265
+ ```
266
+
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)
272
+
273
+ ```bash
274
+ npm install -g @perkos/perkos-a2a
275
+ perkos-a2a-agent pair \
276
+ --invite https://transport.perkos.xyz/pairing/invites/inv_... \
277
+ --agent-name Apollo \
278
+ --runtime hermes-api \
279
+ --capabilities chat,code,research,tasks:receive,messages:send
280
+
281
+ perkos-a2a-hermes \
282
+ --agent-name Apollo \
283
+ --relay-url wss://transport.perkos.xyz/a2a \
284
+ --relay-key "$A2A_RELAY_API_KEY"
285
+ ```
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
+
293
+ Before connecting, validate the local Hermes API Server:
294
+
295
+ ```bash
296
+ curl http://127.0.0.1:8642/health
297
+ curl http://127.0.0.1:8642/v1/capabilities
298
+ ```
299
+
300
+ A healthy bridge keeps an outbound WebSocket open to
301
+ `wss://transport.perkos.xyz/a2a`, so Hermes agents can receive tasks behind NAT,
302
+ Docker, or dynamic IPs without exposing inbound ports.
303
+
109
304
  ## Configuration Reference
110
305
 
111
306
  ```json
@@ -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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"}
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * perkos-a2a-hermes — opinionated CLI wrapper for Hermes deployments.
4
+ *
5
+ * Mirrors the OpenClaw "install one plugin, run it" ergonomics for
6
+ * Hermes users: presets the runtime to `hermes-api`, picks up the
7
+ * Hermes API URL/token/endpoint from the common env var names, and
8
+ * boots the same A2A bridge as `perkos-a2a-agent` — without requiring
9
+ * the operator to remember the runtime-specific flags.
10
+ *
11
+ * Usage:
12
+ * perkos-a2a-hermes \
13
+ * --agent-name Apollo \
14
+ * --relay-url wss://transport.perkos.xyz/a2a \
15
+ * --relay-key "$A2A_RELAY_API_KEY"
16
+ *
17
+ * Env vars consulted (precedence: flags > env):
18
+ * A2A_AGENT_NAME agent name
19
+ * A2A_PORT local A2A port (default 5060)
20
+ * A2A_BIND_HOST bind host (default 0.0.0.0)
21
+ * A2A_PUBLIC_URL advertised base URL
22
+ * A2A_RELAY_URL transport WS URL
23
+ * A2A_RELAY_API_KEY transport relay API key
24
+ * HERMES_API_URL Hermes API base URL (default http://127.0.0.1:8642)
25
+ * HERMES_API_ENDPOINT Hermes API endpoint (default /v1/responses)
26
+ * HERMES_API_KEY Hermes API bearer token
27
+ * A2A_HERMES_SESSION Hermes session key (default a2a)
28
+ */
29
+ export {};
30
+ //# sourceMappingURL=hermes-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hermes-cli.d.ts","sourceRoot":"","sources":["../src/hermes-cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG"}