@perkos/perkos-a2a 0.12.32 → 0.12.33
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 +17 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +74 -20
- package/dist/index.js.map +3 -3
- package/dist/openclaw-supervisor-cli.js +30 -5
- package/dist/openclaw-supervisor-cli.js.map +1 -1
- package/dist/openclaw-supervisor-client.d.ts +3 -0
- package/dist/openclaw-supervisor-client.d.ts.map +1 -1
- package/dist/openclaw-supervisor-client.js +52 -10
- package/dist/openclaw-supervisor-client.js.map +1 -1
- package/dist/openclaw-supervisor.d.ts.map +1 -1
- package/dist/openclaw-supervisor.js +13 -9
- package/dist/openclaw-supervisor.js.map +1 -1
- package/dist/repair.d.ts +11 -1
- package/dist/repair.d.ts.map +1 -1
- package/dist/repair.js +92 -17
- package/dist/repair.js.map +1 -1
- package/dist/runtime-evidence.d.ts +5 -3
- package/dist/runtime-evidence.d.ts.map +1 -1
- package/dist/runtime-evidence.js +4 -1
- package/dist/runtime-evidence.js.map +1 -1
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +6 -1
- package/dist/server.js.map +1 -1
- package/dist/supervisor-protocol.d.ts +28 -13
- package/dist/supervisor-protocol.d.ts.map +1 -1
- package/dist/supervisor-protocol.js +4 -1
- package/dist/supervisor-protocol.js.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -170,7 +170,7 @@ openclaw gateway restart
|
|
|
170
170
|
|
|
171
171
|
#### Official idempotent connection
|
|
172
172
|
|
|
173
|
-
Version 0.12.
|
|
173
|
+
Version 0.12.33+ ships the machine-readable `perkos-a2a connect` CLI. The
|
|
174
174
|
official PerkOS invitation supplies the artifact URL, SHA-256, agent name, and
|
|
175
175
|
agent id; it invokes the exact npm version with `npx`. The same command performs
|
|
176
176
|
a first install or repairs the matching existing identity, even when an invalid
|
|
@@ -206,11 +206,25 @@ failure is emitted as one JSON object; secret values are never printed.
|
|
|
206
206
|
|
|
207
207
|
OpenClaw plugin reloads can briefly keep two JavaScript VMs alive. Starting the
|
|
208
208
|
relay socket in each VM would register the same external identity twice. Version
|
|
209
|
-
0.12.
|
|
209
|
+
0.12.33 moves the relay WebSocket, PerkOS Chat socket, and platform heartbeat to
|
|
210
210
|
one process-external supervisor per normalized relay URL + agent id. Plugin VMs
|
|
211
211
|
communicate with that owner through a private Unix socket and renew a 15-second
|
|
212
212
|
lease.
|
|
213
213
|
|
|
214
|
+
OpenClaw transport ownership is fail-closed: a plugin VM never falls back to a
|
|
215
|
+
second in-process relay/chat/heartbeat client if the supervisor cannot become
|
|
216
|
+
READY and accept the matching claim. The supervisor records its PID, process
|
|
217
|
+
start identity, boot id, claim time, and transport counts in private health
|
|
218
|
+
evidence so `connect` can distinguish a certified owner from stale files.
|
|
219
|
+
|
|
220
|
+
For a clean first install, OpenClaw's PID 1 hot reload remains supported. When
|
|
221
|
+
upgrading a pre-supervisor or otherwise uncertified installation, `connect`
|
|
222
|
+
requires evidence that the gateway PID/start identity actually changed. If the
|
|
223
|
+
current environment cannot perform that restart safely, it exits with the
|
|
224
|
+
machine-readable action `ACTION_REQUIRED_REAL_RESTART`; rerunning the same
|
|
225
|
+
idempotent command after the service/container restart resumes the migration
|
|
226
|
+
without replacing identity or credentials.
|
|
227
|
+
|
|
214
228
|
Each claim carries the parent PID/start identity, boot id, instance id, and
|
|
215
229
|
generation. Before accepting a newer generation, the supervisor waits for
|
|
216
230
|
confirmed transport shutdown; a timeout fails closed with
|
|
@@ -221,7 +235,7 @@ routing.
|
|
|
221
235
|
|
|
222
236
|
```bash
|
|
223
237
|
A2A_RELAY_API_KEY='<credential-from-invitation>' \
|
|
224
|
-
npx --yes @perkos/perkos-a2a@0.12.
|
|
238
|
+
npx --yes @perkos/perkos-a2a@0.12.33 connect \
|
|
225
239
|
--artifact ./perkos-a2a.tgz \
|
|
226
240
|
--sha256 '<sha256-from-the-official-invitation>' \
|
|
227
241
|
--agent-name '<agent-name>' \
|
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;AAaH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAGV,WAAW,EAEZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,cAAc,YAAY,CAAC;AA0C3B,kEAAkE;AAClE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAItF;AAED,KAAK,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AASpD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,OAAO,EACd,oBAAoB,EAAE,MAAM,GAC3B,OAAO,CA2BT;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,oBAAoB,EAC3B,eAAe,CAAC,EAAE,MAAM,GACvB,oBAAoB,CA+BtB;AAiED,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,CAAC,EAAE,KAAK,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,CAAC,CAAC;IACH,IAAI,CAAC,EAAE;QACL,yBAAyB,CAAC,EAAE,MAAM,CAAC;QACnC,qBAAqB,CAAC,EAAE,MAAM,CAAC;KAChC,CAAC;CACH,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAYrF;AAQD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,eAAe,EACvB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE;IAAE,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;CAAE,GAClF,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuFxB;AAYD,oFAAoF;AACpF,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,WAAW,EAAE,EACvB,gBAAgB,EAAE,MAAM,GACvB,MAAM,CAWR;AA4CD,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAe/D;AAED,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAGV,WAAW,EAEZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,cAAc,YAAY,CAAC;AA0C3B,kEAAkE;AAClE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAItF;AAED,KAAK,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AASpD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,OAAO,EACd,oBAAoB,EAAE,MAAM,GAC3B,OAAO,CA2BT;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,oBAAoB,EAC3B,eAAe,CAAC,EAAE,MAAM,GACvB,oBAAoB,CA+BtB;AAiED,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,CAAC,EAAE,KAAK,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,CAAC,CAAC;IACH,IAAI,CAAC,EAAE;QACL,yBAAyB,CAAC,EAAE,MAAM,CAAC;QACnC,qBAAqB,CAAC,EAAE,MAAM,CAAC;KAChC,CAAC;CACH,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAYrF;AAQD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,eAAe,EACvB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE;IAAE,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;CAAE,GAClF,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuFxB;AAYD,oFAAoF;AACpF,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,WAAW,EAAE,EACvB,gBAAgB,EAAE,MAAM,GACvB,MAAM,CAWR;AA4CD,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAe/D;AAED,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,EAAE,GAAG,QAqzBxC"}
|
package/dist/index.js
CHANGED
|
@@ -27009,6 +27009,7 @@ var A2AServer = class {
|
|
|
27009
27009
|
clientOnly = false;
|
|
27010
27010
|
relayClient = null;
|
|
27011
27011
|
externalRelayTransport = false;
|
|
27012
|
+
relayOwnership;
|
|
27012
27013
|
relayHub = null;
|
|
27013
27014
|
messageInjector = null;
|
|
27014
27015
|
taskResultHandler = null;
|
|
@@ -27020,9 +27021,10 @@ var A2AServer = class {
|
|
|
27020
27021
|
startPromise = null;
|
|
27021
27022
|
stopPromise = null;
|
|
27022
27023
|
operations = /* @__PURE__ */ new Set();
|
|
27023
|
-
constructor(config, logger) {
|
|
27024
|
+
constructor(config, logger, options = {}) {
|
|
27024
27025
|
this.config = config;
|
|
27025
27026
|
this.logger = logger || { info: console.log, error: console.error };
|
|
27027
|
+
this.relayOwnership = options.relayOwnership ?? "local";
|
|
27026
27028
|
this.app = (0, import_express.default)();
|
|
27027
27029
|
this.app.use(import_express.default.json());
|
|
27028
27030
|
this.agentCard = {
|
|
@@ -27490,6 +27492,9 @@ var A2AServer = class {
|
|
|
27490
27492
|
this.logger.info(`[perkos-a2a] Relay transport delegated to supervisor for ${relay.url}`);
|
|
27491
27493
|
return;
|
|
27492
27494
|
}
|
|
27495
|
+
if (this.relayOwnership === "external-required") {
|
|
27496
|
+
throw new Error("OWNERSHIP_PRIMITIVE_UNAVAILABLE:OpenClaw relay transport requires the process-external supervisor");
|
|
27497
|
+
}
|
|
27493
27498
|
this.relayClient = new RelayClient({
|
|
27494
27499
|
agentName: this.config.agentName,
|
|
27495
27500
|
relay,
|
|
@@ -27712,7 +27717,7 @@ var A2AServer = class {
|
|
|
27712
27717
|
|
|
27713
27718
|
// src/index.ts
|
|
27714
27719
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
27715
|
-
import { readFileSync as
|
|
27720
|
+
import { readFileSync as readFileSync5 } from "node:fs";
|
|
27716
27721
|
import { dirname as dirname2, resolve as resolve3 } from "node:path";
|
|
27717
27722
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
27718
27723
|
|
|
@@ -28334,6 +28339,7 @@ function isNotFound(err) {
|
|
|
28334
28339
|
// src/openclaw-supervisor-client.ts
|
|
28335
28340
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
28336
28341
|
import { spawn } from "node:child_process";
|
|
28342
|
+
import { existsSync, readFileSync as readFileSync3, unlinkSync } from "node:fs";
|
|
28337
28343
|
import { homedir as homedir3 } from "node:os";
|
|
28338
28344
|
import net from "node:net";
|
|
28339
28345
|
import { resolve } from "node:path";
|
|
@@ -28344,7 +28350,7 @@ import { createHash as createHash2 } from "node:crypto";
|
|
|
28344
28350
|
import { chmodSync, mkdirSync, readFileSync as readFileSync2, renameSync, writeFileSync } from "node:fs";
|
|
28345
28351
|
import { tmpdir } from "node:os";
|
|
28346
28352
|
import { dirname, join as join2 } from "node:path";
|
|
28347
|
-
var SUPERVISOR_PROTOCOL_VERSION =
|
|
28353
|
+
var SUPERVISOR_PROTOCOL_VERSION = 2;
|
|
28348
28354
|
var SUPERVISOR_RENEW_MS = 5e3;
|
|
28349
28355
|
function supervisorOwnerHash(lifecycleKey) {
|
|
28350
28356
|
return createHash2("sha256").update(lifecycleKey).digest("hex");
|
|
@@ -28358,6 +28364,9 @@ function supervisorSocketPath(stateDir, ownerHash) {
|
|
|
28358
28364
|
const uid = typeof process.getuid === "function" ? process.getuid() : "user";
|
|
28359
28365
|
return join2(tmpdir(), `perkos-a2a-${uid}`, `${ownerHash.slice(0, 32)}.sock`);
|
|
28360
28366
|
}
|
|
28367
|
+
function supervisorBootstrapPath(stateDir, ownerHash) {
|
|
28368
|
+
return join2(supervisorDir(stateDir), `${ownerHash}.bootstrap.json`);
|
|
28369
|
+
}
|
|
28361
28370
|
function currentBootId() {
|
|
28362
28371
|
try {
|
|
28363
28372
|
return readFileSync2("/proc/sys/kernel/random/boot_id", "utf8").trim();
|
|
@@ -28388,6 +28397,7 @@ var OpenClawSupervisorClient = class {
|
|
|
28388
28397
|
config;
|
|
28389
28398
|
logger;
|
|
28390
28399
|
handlers;
|
|
28400
|
+
supervisorCliPath;
|
|
28391
28401
|
lease;
|
|
28392
28402
|
socket = null;
|
|
28393
28403
|
startPromise = null;
|
|
@@ -28403,6 +28413,7 @@ var OpenClawSupervisorClient = class {
|
|
|
28403
28413
|
this.config = input.config;
|
|
28404
28414
|
this.logger = input.logger;
|
|
28405
28415
|
this.handlers = input.handlers;
|
|
28416
|
+
this.supervisorCliPath = input.supervisorCliPath;
|
|
28406
28417
|
this.lease = {
|
|
28407
28418
|
ownerKey: input.ownerHash,
|
|
28408
28419
|
instanceId: input.instanceId,
|
|
@@ -28428,13 +28439,18 @@ var OpenClawSupervisorClient = class {
|
|
|
28428
28439
|
this.stopped = false;
|
|
28429
28440
|
const starting = (async () => {
|
|
28430
28441
|
await this.connectOrSpawn();
|
|
28431
|
-
await this.requestWithMessage({
|
|
28432
|
-
protocolVersion:
|
|
28442
|
+
const claim = await this.requestWithMessage({
|
|
28443
|
+
protocolVersion: 2,
|
|
28433
28444
|
type: "claim",
|
|
28434
28445
|
requestId: randomUUID5(),
|
|
28435
28446
|
lease: this.freshLease(),
|
|
28436
28447
|
config: this.config
|
|
28437
28448
|
}, 15e3);
|
|
28449
|
+
const health = claim?.health;
|
|
28450
|
+
if (claim?.state !== "READY" || health?.schemaVersion !== 2 || health.authority !== "process-external-supervisor" || health.state !== "running" || health.ownerKey !== this.ownerHash || health.instanceId !== this.lease.instanceId || health.generation !== this.lease.generation || health.relayClientCount !== (this.config.relay?.enabled && this.config.relay.url ? 1 : 0) || !health.claimedAt) {
|
|
28451
|
+
throw new Error("OWNERSHIP_PRIMITIVE_UNAVAILABLE:supervisor claim did not return certified READY/CLAIMED health");
|
|
28452
|
+
}
|
|
28453
|
+
this.health = health;
|
|
28438
28454
|
this.renewTimer = setInterval(() => this.renew(), SUPERVISOR_RENEW_MS);
|
|
28439
28455
|
this.renewTimer.unref?.();
|
|
28440
28456
|
this.logger.info(`[perkos-a2a] Supervisor owner ready generation=${this.lease.generation} instanceId=${this.lease.instanceId}`);
|
|
@@ -28455,7 +28471,7 @@ var OpenClawSupervisorClient = class {
|
|
|
28455
28471
|
const requestId = randomUUID5();
|
|
28456
28472
|
try {
|
|
28457
28473
|
await this.requestWithMessage({
|
|
28458
|
-
protocolVersion:
|
|
28474
|
+
protocolVersion: 2,
|
|
28459
28475
|
type: "release",
|
|
28460
28476
|
requestId,
|
|
28461
28477
|
lease: this.freshLease()
|
|
@@ -28484,14 +28500,14 @@ var OpenClawSupervisorClient = class {
|
|
|
28484
28500
|
return await this.request("discover", {}, 15e3);
|
|
28485
28501
|
}
|
|
28486
28502
|
sendTaskResponse(original, result) {
|
|
28487
|
-
this.write({ protocolVersion:
|
|
28503
|
+
this.write({ protocolVersion: 2, type: "relayTaskResult", lease: this.freshLease(), eventId: randomUUID5(), original, result });
|
|
28488
28504
|
}
|
|
28489
28505
|
async sendChatReply(payload) {
|
|
28490
28506
|
return await this.request("chatReply", payload, 15e3);
|
|
28491
28507
|
}
|
|
28492
28508
|
async request(method, payload, timeoutMs) {
|
|
28493
28509
|
const requestId = randomUUID5();
|
|
28494
|
-
return this.requestWithMessage({ protocolVersion:
|
|
28510
|
+
return this.requestWithMessage({ protocolVersion: 2, type: "request", requestId, lease: this.freshLease(), method, payload }, timeoutMs);
|
|
28495
28511
|
}
|
|
28496
28512
|
async requestWithMessage(message, timeoutMs) {
|
|
28497
28513
|
return new Promise((resolveRequest, rejectRequest) => {
|
|
@@ -28516,7 +28532,7 @@ var OpenClawSupervisorClient = class {
|
|
|
28516
28532
|
}
|
|
28517
28533
|
renew() {
|
|
28518
28534
|
if (this.stopped || !this.socket || this.socket.destroyed) return;
|
|
28519
|
-
this.write({ protocolVersion:
|
|
28535
|
+
this.write({ protocolVersion: 2, type: "renew", lease: this.freshLease() });
|
|
28520
28536
|
}
|
|
28521
28537
|
async connectOrSpawn() {
|
|
28522
28538
|
try {
|
|
@@ -28524,12 +28540,27 @@ var OpenClawSupervisorClient = class {
|
|
|
28524
28540
|
return;
|
|
28525
28541
|
} catch {
|
|
28526
28542
|
}
|
|
28527
|
-
const cliPath = fileURLToPath(new URL("./openclaw-supervisor-cli.js", import.meta.url));
|
|
28543
|
+
const cliPath = this.supervisorCliPath ?? fileURLToPath(new URL("./openclaw-supervisor-cli.js", import.meta.url));
|
|
28544
|
+
if (!existsSync(cliPath)) {
|
|
28545
|
+
throw new Error(`OWNERSHIP_PRIMITIVE_UNAVAILABLE:supervisor CLI is missing at ${cliPath}`);
|
|
28546
|
+
}
|
|
28547
|
+
const bootstrapPath = supervisorBootstrapPath(this.stateDir, this.ownerHash);
|
|
28548
|
+
try {
|
|
28549
|
+
unlinkSync(bootstrapPath);
|
|
28550
|
+
} catch {
|
|
28551
|
+
}
|
|
28552
|
+
let childExit;
|
|
28528
28553
|
const child = spawn(process.execPath, [cliPath, "--state-dir", this.stateDir, "--owner-key", this.ownerHash], {
|
|
28529
28554
|
detached: true,
|
|
28530
28555
|
stdio: "ignore",
|
|
28531
28556
|
env: { ...process.env }
|
|
28532
28557
|
});
|
|
28558
|
+
child.once("error", (error) => {
|
|
28559
|
+
childExit = `spawn error: ${error.message}`;
|
|
28560
|
+
});
|
|
28561
|
+
child.once("exit", (code, signal) => {
|
|
28562
|
+
childExit = `exit code=${code ?? "null"} signal=${signal ?? "none"}`;
|
|
28563
|
+
});
|
|
28533
28564
|
child.unref();
|
|
28534
28565
|
const deadline = Date.now() + 1e4;
|
|
28535
28566
|
let lastError;
|
|
@@ -28541,9 +28572,22 @@ var OpenClawSupervisorClient = class {
|
|
|
28541
28572
|
} catch (error) {
|
|
28542
28573
|
lastError = error;
|
|
28543
28574
|
}
|
|
28575
|
+
const bootstrap = this.readBootstrapStatus(bootstrapPath);
|
|
28576
|
+
if (bootstrap?.state === "failed") {
|
|
28577
|
+
throw new Error(`OWNERSHIP_PRIMITIVE_UNAVAILABLE:${bootstrap.errorCode || "SUPERVISOR_BOOT_FAILED"}:${bootstrap.message || "supervisor failed before READY"}`);
|
|
28578
|
+
}
|
|
28579
|
+
if (childExit) throw new Error(`OWNERSHIP_PRIMITIVE_UNAVAILABLE:supervisor ${childExit}`);
|
|
28544
28580
|
}
|
|
28545
28581
|
throw new Error(`OWNERSHIP_PRIMITIVE_UNAVAILABLE:${lastError instanceof Error ? lastError.message : String(lastError)}`);
|
|
28546
28582
|
}
|
|
28583
|
+
readBootstrapStatus(path) {
|
|
28584
|
+
try {
|
|
28585
|
+
const value = JSON.parse(readFileSync3(path, "utf8"));
|
|
28586
|
+
return value?.schemaVersion === 1 && value.ownerKey === this.ownerHash ? value : null;
|
|
28587
|
+
} catch {
|
|
28588
|
+
return null;
|
|
28589
|
+
}
|
|
28590
|
+
}
|
|
28547
28591
|
connectSocket(timeoutMs) {
|
|
28548
28592
|
this.closeSocket(new Error("SUPERVISOR_RECONNECT"));
|
|
28549
28593
|
return new Promise((resolveConnect, rejectConnect) => {
|
|
@@ -28609,11 +28653,11 @@ var OpenClawSupervisorClient = class {
|
|
|
28609
28653
|
if (event.type === "relayTask") {
|
|
28610
28654
|
try {
|
|
28611
28655
|
const result = await this.handlers.onRelayTask(event.message);
|
|
28612
|
-
this.write({ protocolVersion:
|
|
28656
|
+
this.write({ protocolVersion: 2, type: "relayTaskResult", lease: this.freshLease(), eventId: event.eventId, original: event.message, result });
|
|
28613
28657
|
} catch (error) {
|
|
28614
28658
|
const message = error instanceof Error ? error.message : String(error);
|
|
28615
28659
|
this.write({
|
|
28616
|
-
protocolVersion:
|
|
28660
|
+
protocolVersion: 2,
|
|
28617
28661
|
type: "relayTaskResult",
|
|
28618
28662
|
lease: this.freshLease(),
|
|
28619
28663
|
eventId: event.eventId,
|
|
@@ -28649,13 +28693,13 @@ import { createHmac } from "node:crypto";
|
|
|
28649
28693
|
import {
|
|
28650
28694
|
chmodSync as chmodSync2,
|
|
28651
28695
|
mkdirSync as mkdirSync2,
|
|
28652
|
-
readFileSync as
|
|
28696
|
+
readFileSync as readFileSync4,
|
|
28653
28697
|
renameSync as renameSync2,
|
|
28654
28698
|
writeFileSync as writeFileSync2
|
|
28655
28699
|
} from "node:fs";
|
|
28656
28700
|
import { homedir as homedir4 } from "node:os";
|
|
28657
28701
|
import { join as join3, resolve as resolve2 } from "node:path";
|
|
28658
|
-
var RUNTIME_EVIDENCE_SCHEMA_VERSION =
|
|
28702
|
+
var RUNTIME_EVIDENCE_SCHEMA_VERSION = 2;
|
|
28659
28703
|
function canonicalize(value) {
|
|
28660
28704
|
if (Array.isArray(value)) return value.map(canonicalize);
|
|
28661
28705
|
if (!value || typeof value !== "object") return value;
|
|
@@ -28688,7 +28732,7 @@ function recordRuntimeLoadEvidence(input) {
|
|
|
28688
28732
|
const evidenceDir = runtimeEvidenceDir(input.stateDir);
|
|
28689
28733
|
let attempt;
|
|
28690
28734
|
try {
|
|
28691
|
-
attempt = JSON.parse(
|
|
28735
|
+
attempt = JSON.parse(readFileSync4(runtimeAttemptPath(input.stateDir), "utf8"));
|
|
28692
28736
|
} catch {
|
|
28693
28737
|
input.logger.info(`[perkos-a2a] config loaded version=${input.version} agentId=${configAgentId(input.config)} attemptId=none`);
|
|
28694
28738
|
return null;
|
|
@@ -28706,6 +28750,8 @@ function recordRuntimeLoadEvidence(input) {
|
|
|
28706
28750
|
fingerprint: configFingerprint(input.config, attempt.hmacKeyHex),
|
|
28707
28751
|
attemptId: attempt.attemptId,
|
|
28708
28752
|
pid: process.pid,
|
|
28753
|
+
processStartTime: processStartIdentity(),
|
|
28754
|
+
bootId: currentBootId(),
|
|
28709
28755
|
pluginRoot: resolve2(input.pluginRoot)
|
|
28710
28756
|
};
|
|
28711
28757
|
mkdirSync2(evidenceDir, { recursive: true, mode: 448 });
|
|
@@ -29149,7 +29195,7 @@ function isWebhookEvent(msg) {
|
|
|
29149
29195
|
// src/index.ts
|
|
29150
29196
|
function loadedPluginVersion() {
|
|
29151
29197
|
try {
|
|
29152
|
-
const manifest = JSON.parse(
|
|
29198
|
+
const manifest = JSON.parse(readFileSync5(new URL("../openclaw.plugin.json", import.meta.url), "utf8"));
|
|
29153
29199
|
return typeof manifest.version === "string" ? manifest.version : "unknown";
|
|
29154
29200
|
} catch {
|
|
29155
29201
|
return "unknown";
|
|
@@ -29438,7 +29484,7 @@ function register(api) {
|
|
|
29438
29484
|
pluginRoot: resolve3(dirname2(fileURLToPath2(import.meta.url)), ".."),
|
|
29439
29485
|
logger
|
|
29440
29486
|
});
|
|
29441
|
-
const server = new A2AServer(pluginConfig, logger);
|
|
29487
|
+
const server = new A2AServer(pluginConfig, logger, { relayOwnership: "external-required" });
|
|
29442
29488
|
const lifecycleKey = a2aLifecycleKey(pluginConfig);
|
|
29443
29489
|
const lifecycleInstanceId = randomUUID7();
|
|
29444
29490
|
const pendingTasks = [];
|
|
@@ -29731,9 +29777,17 @@ function register(api) {
|
|
|
29731
29777
|
api.registerService({
|
|
29732
29778
|
id: "perkos-a2a",
|
|
29733
29779
|
start: async () => {
|
|
29734
|
-
|
|
29735
|
-
|
|
29736
|
-
|
|
29780
|
+
try {
|
|
29781
|
+
await supervisorClient.start();
|
|
29782
|
+
await server.start();
|
|
29783
|
+
logger.info(`[perkos-a2a] A2A server started for ${pluginConfig.agentName}`);
|
|
29784
|
+
} catch (error) {
|
|
29785
|
+
await server.stop({ reason: "openclaw-service-start-failed", timeoutMs: 2e3, drainMs: 0 }).catch(() => void 0);
|
|
29786
|
+
await supervisorClient.stop().catch(() => void 0);
|
|
29787
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
29788
|
+
logger.error(`[perkos-a2a] OWNERSHIP_START_FAILED:${message}`);
|
|
29789
|
+
throw error;
|
|
29790
|
+
}
|
|
29737
29791
|
},
|
|
29738
29792
|
stop: async () => {
|
|
29739
29793
|
logger.info("[perkos-a2a] A2A server stopping");
|