@agentvault/agentvault 0.23.10 → 0.23.12
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/dist/channel.d.ts +35 -0
- package/dist/channel.d.ts.map +1 -1
- package/dist/cli.js +109 -20
- package/dist/cli.js.map +2 -2
- package/dist/index.js +109 -20
- package/dist/index.js.map +2 -2
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -63912,6 +63912,10 @@ var init_channel = __esm({
|
|
|
63912
63912
|
_sessionGroupIds = /* @__PURE__ */ new Map();
|
|
63913
63913
|
/** Consecutive MLS decrypt failure count per group key for epoch recovery. */
|
|
63914
63914
|
_mlsDecryptFailCounts = /* @__PURE__ */ new Map();
|
|
63915
|
+
/** #474: per-group consecutive processCommit failures. Mirrors the decrypt
|
|
63916
|
+
* counter above — a commit that fails is divergence, and divergence must
|
|
63917
|
+
* self-heal rather than be logged and dropped. */
|
|
63918
|
+
_mlsCommitFailCounts = /* @__PURE__ */ new Map();
|
|
63915
63919
|
static MAX_MLS_DECRYPT_FAILS = 3;
|
|
63916
63920
|
/** Cached MLS KeyPackage bundle for this device (regenerated on each connect). */
|
|
63917
63921
|
_mlsKeyPackage = null;
|
|
@@ -64792,7 +64796,7 @@ var init_channel = __esm({
|
|
|
64792
64796
|
*/
|
|
64793
64797
|
sendActivitySpan(spanData) {
|
|
64794
64798
|
if (!this._ws || this._ws.readyState !== WebSocket.OPEN) return;
|
|
64795
|
-
const pluginVersion = true ? "0.23.
|
|
64799
|
+
const pluginVersion = true ? "0.23.12" : "0.0.0-dev";
|
|
64796
64800
|
const agentName = this.config.agentName ?? "Agent";
|
|
64797
64801
|
const resource = {
|
|
64798
64802
|
"service.name": "agentvault-agent",
|
|
@@ -64826,7 +64830,16 @@ var init_channel = __esm({
|
|
|
64826
64830
|
this._ws.send(
|
|
64827
64831
|
JSON.stringify({
|
|
64828
64832
|
event: "worker_heartbeat",
|
|
64829
|
-
data: {
|
|
64833
|
+
data: {
|
|
64834
|
+
worker_capable: h2.workerCapable,
|
|
64835
|
+
armed_rooms: h2.armedRooms,
|
|
64836
|
+
// #20: OPTIONAL on the way in so an older bridge against a newer
|
|
64837
|
+
// plugin still emits a shape the backend can read. `=== true` means
|
|
64838
|
+
// absent/malformed becomes false — the fail-closed direction, and it
|
|
64839
|
+
// never emits `undefined` (which would drop the key entirely).
|
|
64840
|
+
host_trusted: h2.hostTrusted === true,
|
|
64841
|
+
gates_effective: h2.gatesEffective === true
|
|
64842
|
+
}
|
|
64830
64843
|
})
|
|
64831
64844
|
);
|
|
64832
64845
|
}
|
|
@@ -66522,7 +66535,7 @@ var init_channel = __esm({
|
|
|
66522
66535
|
agentVersion: this.config.agentVersion ?? "0.0.0",
|
|
66523
66536
|
// __AV_VERSION__ is injected by esbuild from package.json at build time.
|
|
66524
66537
|
// Falls back to "0.0.0-dev" in non-bundled contexts (tests).
|
|
66525
|
-
pluginVersion: true ? "0.23.
|
|
66538
|
+
pluginVersion: true ? "0.23.12" : "0.0.0-dev"
|
|
66526
66539
|
});
|
|
66527
66540
|
this._telemetryReporter.startAutoFlush(3e4);
|
|
66528
66541
|
}
|
|
@@ -66840,7 +66853,7 @@ var init_channel = __esm({
|
|
|
66840
66853
|
agentVersion: this.config.agentVersion ?? "0.0.0",
|
|
66841
66854
|
// __AV_VERSION__ is injected by esbuild from package.json at build time.
|
|
66842
66855
|
// Falls back to "0.0.0-dev" in non-bundled contexts (tests).
|
|
66843
|
-
pluginVersion: true ? "0.23.
|
|
66856
|
+
pluginVersion: true ? "0.23.12" : "0.0.0-dev"
|
|
66844
66857
|
});
|
|
66845
66858
|
this._telemetryReporter.startAutoFlush(3e4);
|
|
66846
66859
|
}
|
|
@@ -68236,14 +68249,9 @@ ${messageText}`;
|
|
|
68236
68249
|
await saveMlsState(this.config.dataDir, groupId, JSON.stringify(mlsGroup.exportState()));
|
|
68237
68250
|
console.log(`[SecureChannel] MLS commit processed for room ${roomId.slice(0, 8)} (epoch=${mlsGroup.epoch})`);
|
|
68238
68251
|
} catch (err) {
|
|
68239
|
-
|
|
68240
|
-
if (isOldEpoch) {
|
|
68241
|
-
console.log(`[SecureChannel] Discarding old-epoch commit for room ${roomId.slice(0, 8)}`);
|
|
68242
|
-
} else {
|
|
68243
|
-
console.error(`[SecureChannel] MLS commit failed for room ${roomId.slice(0, 8)}:`, err);
|
|
68244
|
-
throw err;
|
|
68245
|
-
}
|
|
68252
|
+
await this._onCommitFailure(roomId, groupId, err, `room ${roomId.slice(0, 8)}`);
|
|
68246
68253
|
}
|
|
68254
|
+
this._mlsCommitFailCounts.delete(roomId);
|
|
68247
68255
|
} else {
|
|
68248
68256
|
this._bufferMlsCommit(groupId, epoch, data);
|
|
68249
68257
|
console.log(`[SecureChannel] Buffered MLS commit for room ${roomId.slice(0, 8)} (epoch=${epoch}, group not initialized)`);
|
|
@@ -68261,14 +68269,9 @@ ${messageText}`;
|
|
|
68261
68269
|
await saveMlsState(this.config.dataDir, groupId, JSON.stringify(mlsGroup.exportState()));
|
|
68262
68270
|
console.log(`[SecureChannel] MLS commit processed for A2A ${chId.slice(0, 8)} (epoch=${mlsGroup.epoch})`);
|
|
68263
68271
|
} catch (err) {
|
|
68264
|
-
|
|
68265
|
-
if (isOldEpoch) {
|
|
68266
|
-
console.log(`[SecureChannel] Discarding old-epoch commit for A2A ${chId.slice(0, 8)}`);
|
|
68267
|
-
} else {
|
|
68268
|
-
console.error(`[SecureChannel] MLS commit failed for A2A ${chId.slice(0, 8)}:`, err);
|
|
68269
|
-
throw err;
|
|
68270
|
-
}
|
|
68272
|
+
await this._onCommitFailure(`a2a:${chId}`, groupId, err, `A2A ${chId.slice(0, 8)}`);
|
|
68271
68273
|
}
|
|
68274
|
+
this._mlsCommitFailCounts.delete(`a2a:${chId}`);
|
|
68272
68275
|
} else {
|
|
68273
68276
|
this._bufferMlsCommit(groupId, epoch, data);
|
|
68274
68277
|
console.log(`[SecureChannel] Buffered MLS commit for A2A ${chId.slice(0, 8)} (epoch=${epoch}, group not initialized)`);
|
|
@@ -68325,6 +68328,52 @@ ${messageText}`;
|
|
|
68325
68328
|
* sends us one. Deduped to a 30s window per group so a burst of undecryptable
|
|
68326
68329
|
* rows doesn't spam request-welcome. Fire-and-forget.
|
|
68327
68330
|
*/
|
|
68331
|
+
/**
|
|
68332
|
+
* #474 — a failed `processCommit` is DIVERGENCE, and divergence must
|
|
68333
|
+
* self-heal. It previously did neither: the room stayed broken forever.
|
|
68334
|
+
*
|
|
68335
|
+
* Two swallow paths existed, and only the second was ever reported:
|
|
68336
|
+
*
|
|
68337
|
+
* 1. `isOldEpoch` substring-matched the error text for "epoch" / "old" /
|
|
68338
|
+
* "Validation" and discarded deliberately. `ValidationError: Desired gen
|
|
68339
|
+
* in the past` contains "Validation", so the LOUDEST production failure
|
|
68340
|
+
* was filed as benign — 1,439 occurrences on one agent, all thrown away
|
|
68341
|
+
* by a string match.
|
|
68342
|
+
* 2. Everything else re-threw to the WS dispatcher, which logs and drops.
|
|
68343
|
+
*
|
|
68344
|
+
* Result: ~1,600 commit failures across 13 rooms and ZERO resyncs. Classifying
|
|
68345
|
+
* divergence by grepping an error message is the root of it — error text is
|
|
68346
|
+
* not a protocol, and the one case that must never be silent was the one that
|
|
68347
|
+
* happened to contain the magic word.
|
|
68348
|
+
*
|
|
68349
|
+
* So: no classification. COUNT, and after MAX_MLS_DECRYPT_FAILS consecutive
|
|
68350
|
+
* failures run the same ladder the decrypt path has used since #440 — replay
|
|
68351
|
+
* the missed commits via /sync, and fall back to re-join only if that cannot
|
|
68352
|
+
* catch up. Counting rather than resyncing on first failure matters: a
|
|
68353
|
+
* genuinely stale commit is normal, and resyncing on each one would have
|
|
68354
|
+
* fired ~1,600 Welcome requests.
|
|
68355
|
+
*
|
|
68356
|
+
* Never re-throws. The caller's only handler logs and drops, so throwing here
|
|
68357
|
+
* is indistinguishable from swallowing — it just moves the swallow one frame up.
|
|
68358
|
+
*/
|
|
68359
|
+
async _onCommitFailure(groupKey, mlsGroupId, err, label) {
|
|
68360
|
+
const count = (this._mlsCommitFailCounts.get(groupKey) ?? 0) + 1;
|
|
68361
|
+
this._mlsCommitFailCounts.set(groupKey, count);
|
|
68362
|
+
console.error(
|
|
68363
|
+
`[SecureChannel] MLS commit failed (${count}/${_SecureChannel.MAX_MLS_DECRYPT_FAILS}) for ${label}:`,
|
|
68364
|
+
err
|
|
68365
|
+
);
|
|
68366
|
+
if (count < _SecureChannel.MAX_MLS_DECRYPT_FAILS) return;
|
|
68367
|
+
console.warn(`[SecureChannel] MLS commit resync triggered for ${label} \u2014 ${count} consecutive failures`);
|
|
68368
|
+
try {
|
|
68369
|
+
if (!await this._resyncOnDivergence(groupKey, mlsGroupId)) {
|
|
68370
|
+
await this._triggerMlsEpochRecovery(groupKey, mlsGroupId);
|
|
68371
|
+
}
|
|
68372
|
+
this._mlsCommitFailCounts.delete(groupKey);
|
|
68373
|
+
} catch (recoverErr) {
|
|
68374
|
+
console.error(`[SecureChannel] MLS commit resync FAILED for ${label}:`, recoverErr);
|
|
68375
|
+
}
|
|
68376
|
+
}
|
|
68328
68377
|
async _requestWelcomeSelfHeal(groupId) {
|
|
68329
68378
|
const now = Date.now();
|
|
68330
68379
|
const last = this._welcomeSelfHealInflight.get(groupId) ?? 0;
|
|
@@ -69126,9 +69175,43 @@ ${messageText}`;
|
|
|
69126
69175
|
const errMsg = addErr instanceof Error ? addErr.message : String(addErr);
|
|
69127
69176
|
if (errMsg.includes("already in the group")) {
|
|
69128
69177
|
console.log(`[SecureChannel] A2A member already in group \u2014 removing and re-adding ${req.requesting_device_id.slice(0, 8)}`);
|
|
69178
|
+
const preRemoveState = JSON.stringify(mlsGroup.exportState());
|
|
69179
|
+
let removeCommitPublished = false;
|
|
69129
69180
|
try {
|
|
69130
69181
|
const identityBytes = new TextEncoder().encode(req.requesting_device_id);
|
|
69131
|
-
|
|
69182
|
+
const leafIndex = mlsGroup.memberLeafIndex(identityBytes);
|
|
69183
|
+
if (leafIndex === null) {
|
|
69184
|
+
console.log(`[SecureChannel] A2A re-add: no leaf index for ${req.requesting_device_id.slice(0, 8)} \u2014 cannot remove`);
|
|
69185
|
+
continue;
|
|
69186
|
+
}
|
|
69187
|
+
const removeResult = await mlsGroup.removeMember(leafIndex);
|
|
69188
|
+
try {
|
|
69189
|
+
const removeResp = await fetch(
|
|
69190
|
+
`${this.config.apiUrl}/api/v1/mls/groups/${chState.mlsGroupId}/distribute`,
|
|
69191
|
+
{
|
|
69192
|
+
method: "POST",
|
|
69193
|
+
headers: { Authorization: `Bearer ${this._deviceJwt}`, "Content-Type": "application/json" },
|
|
69194
|
+
body: JSON.stringify({
|
|
69195
|
+
group_id: chState.mlsGroupId,
|
|
69196
|
+
device_id: this._deviceId,
|
|
69197
|
+
commit: Buffer.from(removeResult.commit).toString("hex"),
|
|
69198
|
+
commit_epoch: Number(mlsGroup.epoch)
|
|
69199
|
+
})
|
|
69200
|
+
}
|
|
69201
|
+
);
|
|
69202
|
+
if (removeResp.ok) {
|
|
69203
|
+
removeCommitPublished = true;
|
|
69204
|
+
} else {
|
|
69205
|
+
const detail = await removeResp.text().catch(() => "");
|
|
69206
|
+
console.warn(`[SecureChannel] A2A remove-commit distribute failed (${removeResp.status}): ${detail}`);
|
|
69207
|
+
}
|
|
69208
|
+
} catch (distErr) {
|
|
69209
|
+
console.warn(`[SecureChannel] A2A remove-commit distribute network error:`, distErr);
|
|
69210
|
+
}
|
|
69211
|
+
if (!removeCommitPublished) {
|
|
69212
|
+
mlsGroup.importState(JSON.parse(preRemoveState));
|
|
69213
|
+
continue;
|
|
69214
|
+
}
|
|
69132
69215
|
const kpRes2 = await fetch(
|
|
69133
69216
|
`${this.config.apiUrl}/api/v1/mls/key-packages/batch?device_ids=${req.requesting_device_id}`,
|
|
69134
69217
|
{ headers: { Authorization: `Bearer ${this._deviceJwt}` } }
|
|
@@ -69152,6 +69235,12 @@ ${messageText}`;
|
|
|
69152
69235
|
}
|
|
69153
69236
|
} catch (readdErr) {
|
|
69154
69237
|
console.log(`[SecureChannel] A2A remove+re-add FAILED: ${readdErr instanceof Error ? readdErr.message : String(readdErr)}`);
|
|
69238
|
+
if (!removeCommitPublished) {
|
|
69239
|
+
try {
|
|
69240
|
+
mlsGroup.importState(JSON.parse(preRemoveState));
|
|
69241
|
+
} catch {
|
|
69242
|
+
}
|
|
69243
|
+
}
|
|
69155
69244
|
continue;
|
|
69156
69245
|
}
|
|
69157
69246
|
} else {
|
|
@@ -97055,7 +97144,7 @@ var init_index = __esm({
|
|
|
97055
97144
|
init_skill_invoker();
|
|
97056
97145
|
await init_skill_telemetry();
|
|
97057
97146
|
await init_policy_enforcer();
|
|
97058
|
-
VERSION = true ? "0.23.
|
|
97147
|
+
VERSION = true ? "0.23.12" : "0.0.0-dev";
|
|
97059
97148
|
}
|
|
97060
97149
|
});
|
|
97061
97150
|
await init_index();
|