@agentvault/agentvault 0.23.20 → 0.23.21
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 +39 -0
- package/dist/channel.d.ts.map +1 -1
- package/dist/cli.js +114 -4
- package/dist/cli.js.map +3 -3
- package/dist/index.js +114 -4
- package/dist/index.js.map +3 -3
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -64066,6 +64066,17 @@ var init_channel = __esm({
|
|
|
64066
64066
|
_pendingPollTimer = null;
|
|
64067
64067
|
_syncMessageIds = null;
|
|
64068
64068
|
_deliveryHeartbeat = null;
|
|
64069
|
+
/**
|
|
64070
|
+
* How often to re-check the KeyPackage pool against the server (#826).
|
|
64071
|
+
*
|
|
64072
|
+
* KeyPackages expire after 7 days and, before this, only a reconnect
|
|
64073
|
+
* republished them — so an agent that simply stayed up ran to zero usable
|
|
64074
|
+
* and silently stopped accepting new MLS 1:1 conversations while looking
|
|
64075
|
+
* perfectly healthy. 6h gives ~28 attempts inside one lifetime, so a run of
|
|
64076
|
+
* transient failures cannot age the pool out. Cost is one GET per interval.
|
|
64077
|
+
*/
|
|
64078
|
+
static _KP_REPLENISH_INTERVAL_MS = 6 * 60 * 60 * 1e3;
|
|
64079
|
+
_kpReplenishTimer = null;
|
|
64069
64080
|
_a2aReconcileTimer = null;
|
|
64070
64081
|
_deliveryPulling = false;
|
|
64071
64082
|
_drDeliveryPulling = false;
|
|
@@ -65030,7 +65041,7 @@ var init_channel = __esm({
|
|
|
65030
65041
|
*/
|
|
65031
65042
|
sendActivitySpan(spanData) {
|
|
65032
65043
|
if (!this._ws || this._ws.readyState !== WebSocket.OPEN) return;
|
|
65033
|
-
const pluginVersion = true ? "0.23.
|
|
65044
|
+
const pluginVersion = true ? "0.23.21" : "0.0.0-dev";
|
|
65034
65045
|
const agentName = this.config.agentName ?? "Agent";
|
|
65035
65046
|
const resource = {
|
|
65036
65047
|
"service.name": "agentvault-agent",
|
|
@@ -66940,7 +66951,7 @@ var init_channel = __esm({
|
|
|
66940
66951
|
agentVersion: this.config.agentVersion ?? "0.0.0",
|
|
66941
66952
|
// __AV_VERSION__ is injected by esbuild from package.json at build time.
|
|
66942
66953
|
// Falls back to "0.0.0-dev" in non-bundled contexts (tests).
|
|
66943
|
-
pluginVersion: true ? "0.23.
|
|
66954
|
+
pluginVersion: true ? "0.23.21" : "0.0.0-dev"
|
|
66944
66955
|
});
|
|
66945
66956
|
this._telemetryReporter.startAutoFlush(3e4);
|
|
66946
66957
|
}
|
|
@@ -66949,6 +66960,7 @@ var init_channel = __esm({
|
|
|
66949
66960
|
console.warn("[SecureChannel] A2A channel sync on connect failed:", err);
|
|
66950
66961
|
});
|
|
66951
66962
|
await this._ensureKpPoolPublished();
|
|
66963
|
+
this._startKpReplenishTimer();
|
|
66952
66964
|
this._pullDeliveryQueue().catch((err) => {
|
|
66953
66965
|
console.warn("[SecureChannel] Initial delivery pull failed:", err);
|
|
66954
66966
|
});
|
|
@@ -67263,7 +67275,7 @@ var init_channel = __esm({
|
|
|
67263
67275
|
agentVersion: this.config.agentVersion ?? "0.0.0",
|
|
67264
67276
|
// __AV_VERSION__ is injected by esbuild from package.json at build time.
|
|
67265
67277
|
// Falls back to "0.0.0-dev" in non-bundled contexts (tests).
|
|
67266
|
-
pluginVersion: true ? "0.23.
|
|
67278
|
+
pluginVersion: true ? "0.23.21" : "0.0.0-dev"
|
|
67267
67279
|
});
|
|
67268
67280
|
this._telemetryReporter.startAutoFlush(3e4);
|
|
67269
67281
|
}
|
|
@@ -67606,6 +67618,7 @@ var init_channel = __esm({
|
|
|
67606
67618
|
this._deliveryHeartbeat = null;
|
|
67607
67619
|
}
|
|
67608
67620
|
this._stopA2aReconcileTimer();
|
|
67621
|
+
this._stopKpReplenishTimer();
|
|
67609
67622
|
if (this._stopped) return;
|
|
67610
67623
|
this._setState("disconnected");
|
|
67611
67624
|
this._scheduleReconnect();
|
|
@@ -68999,6 +69012,103 @@ ${messageText}`;
|
|
|
68999
69012
|
this._kpPoolFilling = false;
|
|
69000
69013
|
}
|
|
69001
69014
|
}
|
|
69015
|
+
/** Start the periodic KeyPackage replenish (#826). Idempotent. */
|
|
69016
|
+
_startKpReplenishTimer() {
|
|
69017
|
+
this._stopKpReplenishTimer();
|
|
69018
|
+
this._kpReplenishTimer = setInterval(() => {
|
|
69019
|
+
void this._replenishKpPoolFromServer();
|
|
69020
|
+
}, _SecureChannel._KP_REPLENISH_INTERVAL_MS);
|
|
69021
|
+
}
|
|
69022
|
+
_stopKpReplenishTimer() {
|
|
69023
|
+
if (this._kpReplenishTimer) {
|
|
69024
|
+
clearInterval(this._kpReplenishTimer);
|
|
69025
|
+
this._kpReplenishTimer = null;
|
|
69026
|
+
}
|
|
69027
|
+
}
|
|
69028
|
+
/**
|
|
69029
|
+
* The server's EXPIRY-AWARE usable KeyPackage count, or null when unknown.
|
|
69030
|
+
*
|
|
69031
|
+
* `count_unconsumed` filters `expires_at > utcnow()`, which is the only count
|
|
69032
|
+
* that reflects what a peer can actually fetch. Returns null (not 0) on any
|
|
69033
|
+
* failure so callers can tell "server says empty" from "we could not ask" —
|
|
69034
|
+
* guessing 0 here would publish a fresh pool on every transient 503.
|
|
69035
|
+
*/
|
|
69036
|
+
async _fetchServerKpCount() {
|
|
69037
|
+
try {
|
|
69038
|
+
const res = await fetch(
|
|
69039
|
+
`${this.config.apiUrl}/api/v1/mls/key-packages/count?device_id=${this._deviceId}`,
|
|
69040
|
+
{ headers: { Authorization: `Bearer ${this._deviceJwt}` } }
|
|
69041
|
+
);
|
|
69042
|
+
if (!res.ok) return null;
|
|
69043
|
+
const body = await res.json();
|
|
69044
|
+
const n2 = body?.count;
|
|
69045
|
+
return typeof n2 === "number" && Number.isFinite(n2) ? n2 : null;
|
|
69046
|
+
} catch {
|
|
69047
|
+
return null;
|
|
69048
|
+
}
|
|
69049
|
+
}
|
|
69050
|
+
/**
|
|
69051
|
+
* Top the pool up against the SERVER's count (#826).
|
|
69052
|
+
*
|
|
69053
|
+
* ⚠️ DO NOT replace this with a periodic call to `_ensureKpPoolPublished()`.
|
|
69054
|
+
* That function early-returns on `_pendingKpBundles.length >= _KP_POOL_TARGET`,
|
|
69055
|
+
* and that array holds PRIVATE bundles which never expire locally — so on an
|
|
69056
|
+
* agent that has been connected longer than the KeyPackage lifetime it is
|
|
69057
|
+
* still full while the server has zero usable. Measured on prod 2026-08-09:
|
|
69058
|
+
* cortina and eclaude were online and green with 10 unconsumed / 0 usable,
|
|
69059
|
+
* unable to accept any new MLS 1:1. A timer over the local guard would have
|
|
69060
|
+
* run forever and changed nothing.
|
|
69061
|
+
*
|
|
69062
|
+
* Publishes only the shortfall, and never throws — this runs on a timer and
|
|
69063
|
+
* must not be able to take the channel down.
|
|
69064
|
+
*/
|
|
69065
|
+
async _replenishKpPoolFromServer() {
|
|
69066
|
+
try {
|
|
69067
|
+
if (this._kpPoolFilling) return;
|
|
69068
|
+
const usable = await this._fetchServerKpCount();
|
|
69069
|
+
if (usable === null) return;
|
|
69070
|
+
const shortfall = _SecureChannel._KP_POOL_TARGET - usable;
|
|
69071
|
+
if (shortfall <= 0) return;
|
|
69072
|
+
this._kpPoolFilling = true;
|
|
69073
|
+
try {
|
|
69074
|
+
const identity = new TextEncoder().encode(this._deviceId);
|
|
69075
|
+
let published = 0;
|
|
69076
|
+
for (let i2 = 0; i2 < shortfall; i2++) {
|
|
69077
|
+
const mlsMgr = new MLSGroupManager();
|
|
69078
|
+
const kp = await mlsMgr.generateKeyPackage(identity);
|
|
69079
|
+
const kpHex = Buffer.from(
|
|
69080
|
+
MLSGroupManager.serializeKeyPackage(kp.publicPackage)
|
|
69081
|
+
).toString("hex");
|
|
69082
|
+
const res = await fetch(`${this.config.apiUrl}/api/v1/mls/key-packages`, {
|
|
69083
|
+
method: "POST",
|
|
69084
|
+
headers: {
|
|
69085
|
+
Authorization: `Bearer ${this._deviceJwt}`,
|
|
69086
|
+
"Content-Type": "application/json"
|
|
69087
|
+
},
|
|
69088
|
+
body: JSON.stringify({ key_package: kpHex })
|
|
69089
|
+
});
|
|
69090
|
+
if (!res.ok) {
|
|
69091
|
+
console.warn(
|
|
69092
|
+
`[SecureChannel] KeyPackage replenish rejected (status ${res.status}) after ${published}/${shortfall}`
|
|
69093
|
+
);
|
|
69094
|
+
break;
|
|
69095
|
+
}
|
|
69096
|
+
this._recordPublishedKp(kp);
|
|
69097
|
+
if (!this._mlsKeyPackage) this._mlsKeyPackage = kp;
|
|
69098
|
+
published++;
|
|
69099
|
+
}
|
|
69100
|
+
if (published > 0) {
|
|
69101
|
+
console.log(
|
|
69102
|
+
`[SecureChannel] MLS KeyPackage pool replenished (${published} new; server had ${usable}/${_SecureChannel._KP_POOL_TARGET} usable)`
|
|
69103
|
+
);
|
|
69104
|
+
}
|
|
69105
|
+
} finally {
|
|
69106
|
+
this._kpPoolFilling = false;
|
|
69107
|
+
}
|
|
69108
|
+
} catch (err) {
|
|
69109
|
+
console.warn("[SecureChannel] KeyPackage replenish failed:", err);
|
|
69110
|
+
}
|
|
69111
|
+
}
|
|
69002
69112
|
async _handleMlsWelcome(data) {
|
|
69003
69113
|
const groupId = data.group_id;
|
|
69004
69114
|
const conversationId = data.conversation_id;
|
|
@@ -97592,7 +97702,7 @@ var init_index = __esm({
|
|
|
97592
97702
|
init_skill_invoker();
|
|
97593
97703
|
await init_skill_telemetry();
|
|
97594
97704
|
await init_policy_enforcer();
|
|
97595
|
-
VERSION = true ? "0.23.
|
|
97705
|
+
VERSION = true ? "0.23.21" : "0.0.0-dev";
|
|
97596
97706
|
}
|
|
97597
97707
|
});
|
|
97598
97708
|
await init_index();
|