@perkos/perkos-a2a 0.12.57 → 0.12.58
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 +89 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -0
- package/dist/index.js.map +3 -3
- package/openclaw.plugin.json +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -130,6 +130,31 @@ curl -s -X POST http://localhost:5050/a2a/jsonrpc \
|
|
|
130
130
|
-d '{"jsonrpc":"2.0","method":"tasks/list","id":1,"params":{}}' | python3 -m json.tool
|
|
131
131
|
```
|
|
132
132
|
|
|
133
|
+
## Which one do you need: plugin or standalone bridge?
|
|
134
|
+
|
|
135
|
+
This package ships **two different entry points**, and picking the wrong one is
|
|
136
|
+
the most common way to end up with an agent that looks connected but never does
|
|
137
|
+
any work.
|
|
138
|
+
|
|
139
|
+
| | In-runtime plugin (`index.ts`) | Standalone bridge (`bridge-agent.ts`) |
|
|
140
|
+
|---|---|---|
|
|
141
|
+
| How it runs | Loaded inside the OpenClaw gateway process | Its own process (`perkos-a2a-agent`) |
|
|
142
|
+
| Chat + A2A peer tasks | Yes | Yes |
|
|
143
|
+
| **PerkOS job-board work** | **No** | **Yes** |
|
|
144
|
+
| Reads the dispatcher's board scope | No | Yes |
|
|
145
|
+
| Reply sent back to the caller | Synthesized by the bridge | The runtime's real answer |
|
|
146
|
+
| Board MCP tools (`updateTaskStatus`, …) | Not hosted | Hosted on loopback |
|
|
147
|
+
|
|
148
|
+
**If the agent has to pick up tasks from a PerkOS board, you need the standalone
|
|
149
|
+
bridge.** This is true for **both** runtimes: it is not a Hermes-only concern.
|
|
150
|
+
The in-runtime plugin ignores the board scope the dispatcher attaches to a task
|
|
151
|
+
and completes the A2A task with a reply it synthesizes itself, so the board
|
|
152
|
+
never advances and the dispatcher burns its retries against a plausible-looking
|
|
153
|
+
answer.
|
|
154
|
+
|
|
155
|
+
Run **one** of them, never both against the same agent: two listeners will both
|
|
156
|
+
answer the same inbound task.
|
|
157
|
+
|
|
133
158
|
## Quick Start
|
|
134
159
|
|
|
135
160
|
```bash
|
|
@@ -161,6 +186,12 @@ pairing flow. Do not share one global relay key across production agents.
|
|
|
161
186
|
|
|
162
187
|
### OpenClaw agent
|
|
163
188
|
|
|
189
|
+
> **Board work needs the standalone bridge, not this plugin.** Installing the
|
|
190
|
+
> plugin gives an OpenClaw agent chat and peer-to-peer A2A. It does **not** let
|
|
191
|
+
> it work a PerkOS job board. See
|
|
192
|
+
> [Which one do you need](#which-one-do-you-need-plugin-or-standalone-bridge)
|
|
193
|
+
> and [PerkOS board tools](#perkos-board-tools-job-board-over-mcp).
|
|
194
|
+
|
|
164
195
|
OpenClaw agents install `@perkos/perkos-a2a` as an OpenClaw plugin:
|
|
165
196
|
|
|
166
197
|
```bash
|
|
@@ -510,7 +541,10 @@ OpenClaw uses `enqueueSystemEvent` + `requestHeartbeatNow` when available.
|
|
|
510
541
|
|
|
511
542
|
Hermes delivery uses the supported Hermes API Server HTTP surface. By default the bridge posts to `/v1/responses`; `/v1/runs` is available when you want observable run state/events, and `/v1/chat/completions` is available for OpenAI-compatible chat payloads. Validate the local Hermes API Server with `GET /health` and `GET /v1/capabilities`. Do not use UI/workspace endpoints such as `/api/session-send` or `/api/sessions/send`; those are not the stable Hermes runtime delivery interface.
|
|
512
543
|
|
|
513
|
-
Hermes does not load OpenClaw plugins, so
|
|
544
|
+
Hermes does not load OpenClaw plugins, so a Hermes agent always runs the standalone
|
|
545
|
+
bridge. Note this is not the only reason to run it: an **OpenClaw** agent that has to
|
|
546
|
+
work a PerkOS board needs the standalone bridge too (point `HERMES_API_URL` at the
|
|
547
|
+
OpenClaw gateway and set `A2A_RUNTIME=openclaw`). Run it with API Server enabled:
|
|
514
548
|
|
|
515
549
|
```bash
|
|
516
550
|
A2A_AGENT_NAME=hermes-agent \
|
|
@@ -672,6 +706,60 @@ When the plugin is active, three tools are available to the agent:
|
|
|
672
706
|
| `perkos_a2a_send` | Send a task to a named peer (direct HTTP → relay fallback) |
|
|
673
707
|
| `perkos_a2a_status` | Check the status of a previously sent task by ID |
|
|
674
708
|
|
|
709
|
+
These three are the plugin's **entire** tool surface. Job-board tools are not
|
|
710
|
+
here: they are served over MCP by the standalone bridge, below.
|
|
711
|
+
|
|
712
|
+
## PerkOS board tools (job board over MCP)
|
|
713
|
+
|
|
714
|
+
To let an agent actually work a PerkOS job board (claim a task, move it to
|
|
715
|
+
Done, post to the project chat), the **standalone bridge** hosts a local MCP
|
|
716
|
+
server exposing the board tools natively. The model calls them like any other
|
|
717
|
+
tool: no shell, no `execute_code`, no approval gate. It works for **both**
|
|
718
|
+
runtimes, Hermes and OpenClaw.
|
|
719
|
+
|
|
720
|
+
The bridge mints a wallet-scoped, short-lived JWT per call using
|
|
721
|
+
`A2A_TOOLS_JWT_SECRET`, which never leaves the bridge process. The model never
|
|
722
|
+
supplies a wallet, only board arguments such as `projectId`.
|
|
723
|
+
|
|
724
|
+
Tools exposed: `createTask`, `updateTaskStatus`, `listProjectTasks`,
|
|
725
|
+
`postProjectMessage`, `listDocs`, `createDoc`, `readDoc`, `upsertPlanGroup`,
|
|
726
|
+
`upsertPlanTask`, `proposePlan`, `postDocMessage`.
|
|
727
|
+
|
|
728
|
+
### Enabling it
|
|
729
|
+
|
|
730
|
+
All three of these must be set on the **bridge** process, or the board MCP
|
|
731
|
+
server silently does not start:
|
|
732
|
+
|
|
733
|
+
| Variable | Required | Notes |
|
|
734
|
+
|---|---|---|
|
|
735
|
+
| `A2A_TOOLS_JWT_SECRET` | yes | Must be **>=32 characters**, or the listener is disabled. Must equal the Tools API's `JWT_SHARED_SECRET`. |
|
|
736
|
+
| `A2A_TOOLS_API_URL` | yes | e.g. `https://api.perkos.xyz/tools` |
|
|
737
|
+
| `PERKOS_OWNER_WALLET` | yes | The board owner's wallet. **Without it the board MCP server is disabled** and the agent has no way to move a task. |
|
|
738
|
+
| `A2A_BOARD_MCP_PORT` | no | Defaults to `5071`. |
|
|
739
|
+
| `A2A_TOOLS_TOKEN_TTL_SECONDS` | no | Defaults to `60`. |
|
|
740
|
+
|
|
741
|
+
Startup is logged. If you see this line, the agent can receive board tasks but
|
|
742
|
+
can never complete them:
|
|
743
|
+
|
|
744
|
+
```
|
|
745
|
+
[board-mcp] PERKOS_OWNER_WALLET unset — board MCP server disabled (set it to enable native job-board tools)
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
Then point the runtime's MCP client at `http://127.0.0.1:5071` (transport:
|
|
749
|
+
MCP streamable-http). The server binds loopback only.
|
|
750
|
+
|
|
751
|
+
### Symptom checklist
|
|
752
|
+
|
|
753
|
+
An agent that is assigned board tasks but never moves them usually has one of:
|
|
754
|
+
|
|
755
|
+
1. It is running the **in-runtime plugin** instead of the standalone bridge, so
|
|
756
|
+
the board scope never reaches it and the reply is synthesized. Check for a
|
|
757
|
+
separate `perkos-a2a-agent` / `bridge-agent.js` process; if there is none,
|
|
758
|
+
this is your problem.
|
|
759
|
+
2. `PERKOS_OWNER_WALLET` is unset, so the board tools were never served.
|
|
760
|
+
3. `A2A_TOOLS_JWT_SECRET` is shorter than 32 characters, or does not match the
|
|
761
|
+
Tools API secret.
|
|
762
|
+
|
|
675
763
|
## CLI Commands
|
|
676
764
|
|
|
677
765
|
```bash
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -27782,6 +27782,22 @@ import { readFileSync as readFileSync5 } from "node:fs";
|
|
|
27782
27782
|
import { dirname as dirname3, resolve as resolve3 } from "node:path";
|
|
27783
27783
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
27784
27784
|
|
|
27785
|
+
// src/task-context.ts
|
|
27786
|
+
function perkosTaskContext(task, trustedDispatcher = process.env.PERKOS_DISPATCHER_AGENT_NAME || "perkos-ci-probe-dispatcher") {
|
|
27787
|
+
const metadata = task.metadata;
|
|
27788
|
+
if (metadata?.fromAgent !== trustedDispatcher) return void 0;
|
|
27789
|
+
const raw = metadata.perkosBoard;
|
|
27790
|
+
if (!raw || typeof raw !== "object") return void 0;
|
|
27791
|
+
const value = raw;
|
|
27792
|
+
if (typeof value.wallet !== "string" || typeof value.convId !== "string") {
|
|
27793
|
+
return void 0;
|
|
27794
|
+
}
|
|
27795
|
+
const wallet = value.wallet.trim().toLowerCase();
|
|
27796
|
+
const convId = value.convId.trim();
|
|
27797
|
+
if (!/^0x[0-9a-f]{40}$/.test(wallet) || !convId) return void 0;
|
|
27798
|
+
return { wallet, convId };
|
|
27799
|
+
}
|
|
27800
|
+
|
|
27785
27801
|
// src/agentic-actions.ts
|
|
27786
27802
|
var FALLBACK_AGENT_ALIASES = [
|
|
27787
27803
|
["Perkos-Claw-Tester", ["perkos-claw-tester", "openclaw", "open claw", "claw"]],
|
|
@@ -29654,6 +29670,7 @@ function isWebhookEvent(msg) {
|
|
|
29654
29670
|
}
|
|
29655
29671
|
|
|
29656
29672
|
// src/index.ts
|
|
29673
|
+
var warnedBoardTaskUnsupported = false;
|
|
29657
29674
|
function loadedPluginVersion() {
|
|
29658
29675
|
try {
|
|
29659
29676
|
const manifest = JSON.parse(readFileSync5(new URL("../openclaw.plugin.json", import.meta.url), "utf8"));
|
|
@@ -30158,6 +30175,12 @@ function register(api) {
|
|
|
30158
30175
|
});
|
|
30159
30176
|
return;
|
|
30160
30177
|
}
|
|
30178
|
+
if (!warnedBoardTaskUnsupported && perkosTaskContext(task)) {
|
|
30179
|
+
warnedBoardTaskUnsupported = true;
|
|
30180
|
+
logger.error(
|
|
30181
|
+
'[perkos-a2a] This is a PerkOS BOARD task, and the in-runtime plugin cannot work a board. It will be answered with a synthesized reply and the task will never move. Run the standalone bridge (perkos-a2a-agent) for this agent instead, with A2A_TOOLS_JWT_SECRET, A2A_TOOLS_API_URL and PERKOS_OWNER_WALLET set, then disable this plugin so both do not answer the same task. See the README section "Which one do you need: plugin or standalone bridge?".'
|
|
30182
|
+
);
|
|
30183
|
+
}
|
|
30161
30184
|
task.artifacts.push({
|
|
30162
30185
|
kind: "artifact",
|
|
30163
30186
|
artifactId: randomUUID7(),
|