@agentvault/agentvault 0.9.5 → 0.9.7
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/__tests__/crypto-helpers.test.d.ts +2 -0
- package/dist/__tests__/crypto-helpers.test.d.ts.map +1 -0
- package/dist/__tests__/functional.test.d.ts +21 -0
- package/dist/__tests__/functional.test.d.ts.map +1 -0
- package/dist/__tests__/multi-session.test.d.ts +2 -0
- package/dist/__tests__/multi-session.test.d.ts.map +1 -0
- package/dist/__tests__/state.test.d.ts +2 -0
- package/dist/__tests__/state.test.d.ts.map +1 -0
- package/dist/__tests__/transport.test.d.ts +2 -0
- package/dist/__tests__/transport.test.d.ts.map +1 -0
- package/dist/channel.d.ts +6 -2
- package/dist/channel.d.ts.map +1 -1
- package/dist/channel.js +2257 -0
- package/dist/channel.js.map +1 -0
- package/dist/cli.js +336 -91
- package/dist/cli.js.map +4 -4
- package/dist/crypto-helpers.js +4 -0
- package/dist/crypto-helpers.js.map +1 -0
- package/dist/index.js +313 -91
- package/dist/index.js.map +4 -4
- package/dist/openclaw-entry.js +1 -1
- package/dist/openclaw-entry.js.map +2 -2
- package/dist/openclaw-plugin.js +222 -0
- package/dist/openclaw-plugin.js.map +1 -0
- package/dist/setup.js +329 -0
- package/dist/setup.js.map +1 -0
- package/dist/state.js +61 -0
- package/dist/state.js.map +1 -0
- package/dist/transport.js +43 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -10,7 +10,7 @@ var __export = (target, all) => {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
// ../../node_modules/libsodium-sumo/dist/modules-sumo-esm/libsodium-sumo.mjs
|
|
13
|
-
var __filename, __dirname, url, path, Module, Module, root, window_, crypto_, randomValuesStandard,
|
|
13
|
+
var __filename, __dirname, url, path, Module, Module, root, window_, crypto_, randomValuesStandard, crypto2, randomValueNodeJS, _Module, libsodium_sumo_default;
|
|
14
14
|
var init_libsodium_sumo = __esm({
|
|
15
15
|
async "../../node_modules/libsodium-sumo/dist/modules-sumo-esm/libsodium-sumo.mjs"() {
|
|
16
16
|
try {
|
|
@@ -74,9 +74,9 @@ var init_libsodium_sumo = __esm({
|
|
|
74
74
|
Module.getRandomValue = randomValuesStandard;
|
|
75
75
|
} catch (e) {
|
|
76
76
|
try {
|
|
77
|
-
|
|
77
|
+
crypto2 = null;
|
|
78
78
|
randomValueNodeJS = function() {
|
|
79
|
-
var buf =
|
|
79
|
+
var buf = crypto2["randomBytes"](4);
|
|
80
80
|
return (buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]) >>> 0;
|
|
81
81
|
};
|
|
82
82
|
randomValueNodeJS();
|
|
@@ -40279,7 +40279,7 @@ var init_libsodium_sumo = __esm({
|
|
|
40279
40279
|
try {
|
|
40280
40280
|
var window_ = "object" === typeof window ? window : self;
|
|
40281
40281
|
var crypto_ = typeof window_.crypto !== "undefined" ? window_.crypto : window_.msCrypto;
|
|
40282
|
-
crypto_ = crypto_ === void 0 ?
|
|
40282
|
+
crypto_ = crypto_ === void 0 ? crypto2 : crypto_;
|
|
40283
40283
|
var randomValuesStandard = function() {
|
|
40284
40284
|
var buf = new Uint32Array(1);
|
|
40285
40285
|
crypto_.getRandomValues(buf);
|
|
@@ -40289,9 +40289,9 @@ var init_libsodium_sumo = __esm({
|
|
|
40289
40289
|
Module3.getRandomValue = randomValuesStandard;
|
|
40290
40290
|
} catch (e) {
|
|
40291
40291
|
try {
|
|
40292
|
-
var
|
|
40292
|
+
var crypto2 = null;
|
|
40293
40293
|
var randomValueNodeJS = function() {
|
|
40294
|
-
var buf =
|
|
40294
|
+
var buf = crypto2["randomBytes"](4);
|
|
40295
40295
|
return (buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]) >>> 0;
|
|
40296
40296
|
};
|
|
40297
40297
|
randomValueNodeJS();
|
|
@@ -41339,7 +41339,7 @@ var init_libsodium_sumo = __esm({
|
|
|
41339
41339
|
try {
|
|
41340
41340
|
var window_ = "object" === typeof window ? window : self;
|
|
41341
41341
|
var crypto_ = typeof window_.crypto !== "undefined" ? window_.crypto : window_.msCrypto;
|
|
41342
|
-
crypto_ = crypto_ === void 0 ?
|
|
41342
|
+
crypto_ = crypto_ === void 0 ? crypto2 : crypto_;
|
|
41343
41343
|
var randomValuesStandard = function() {
|
|
41344
41344
|
var buf = new Uint32Array(1);
|
|
41345
41345
|
crypto_.getRandomValues(buf);
|
|
@@ -41349,9 +41349,9 @@ var init_libsodium_sumo = __esm({
|
|
|
41349
41349
|
Module2.getRandomValue = randomValuesStandard;
|
|
41350
41350
|
} catch (e) {
|
|
41351
41351
|
try {
|
|
41352
|
-
var
|
|
41352
|
+
var crypto2 = null;
|
|
41353
41353
|
var randomValueNodeJS = function() {
|
|
41354
|
-
var buf =
|
|
41354
|
+
var buf = crypto2["randomBytes"](4);
|
|
41355
41355
|
return (buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]) >>> 0;
|
|
41356
41356
|
};
|
|
41357
41357
|
randomValueNodeJS();
|
|
@@ -44783,6 +44783,22 @@ var init_ratchet = __esm({
|
|
|
44783
44783
|
const currentDhHex = this.state.dhReceivingPublicKey ? libsodium_wrappers_default.to_hex(this.state.dhReceivingPublicKey) : null;
|
|
44784
44784
|
if (currentDhHex === null && this.state.receivingChain) {
|
|
44785
44785
|
this.state.dhReceivingPublicKey = message.header.dhPublicKey;
|
|
44786
|
+
} else if (currentDhHex === null && !this.state.receivingChain) {
|
|
44787
|
+
if (message.header.messageNumber === 0) {
|
|
44788
|
+
try {
|
|
44789
|
+
const { messageKey: testKey, nextChainKey: nextChainKey2 } = kdfChainKey(this.state.rootKey);
|
|
44790
|
+
const ad2 = serializeHeader(message.header);
|
|
44791
|
+
const ptBytes = libsodium_wrappers_default.crypto_aead_xchacha20poly1305_ietf_decrypt(null, message.ciphertext, ad2, message.nonce, testKey);
|
|
44792
|
+
this.state.dhReceivingPublicKey = message.header.dhPublicKey;
|
|
44793
|
+
this.state.receivingChain = {
|
|
44794
|
+
chainKey: nextChainKey2,
|
|
44795
|
+
messageNumber: 1
|
|
44796
|
+
};
|
|
44797
|
+
return libsodium_wrappers_default.to_string(ptBytes);
|
|
44798
|
+
} catch {
|
|
44799
|
+
}
|
|
44800
|
+
}
|
|
44801
|
+
this.dhRatchetReceive(message.header.dhPublicKey);
|
|
44786
44802
|
} else if (headerDhHex !== currentDhHex) {
|
|
44787
44803
|
if (this.state.receivingChain && this.state.dhReceivingPublicKey) {
|
|
44788
44804
|
this.skipMessages(this.state.receivingChain, message.header.previousChainLength, this.state.dhReceivingPublicKey);
|
|
@@ -45151,6 +45167,14 @@ var init_merkle = __esm({
|
|
|
45151
45167
|
}
|
|
45152
45168
|
});
|
|
45153
45169
|
|
|
45170
|
+
// ../crypto/dist/vc.js
|
|
45171
|
+
var init_vc = __esm({
|
|
45172
|
+
async "../crypto/dist/vc.js"() {
|
|
45173
|
+
"use strict";
|
|
45174
|
+
await init_did();
|
|
45175
|
+
}
|
|
45176
|
+
});
|
|
45177
|
+
|
|
45154
45178
|
// ../crypto/dist/transport.js
|
|
45155
45179
|
function hexToBytes(hex) {
|
|
45156
45180
|
return libsodium_wrappers_default.from_hex(hex);
|
|
@@ -45200,6 +45224,220 @@ var init_transport = __esm({
|
|
|
45200
45224
|
}
|
|
45201
45225
|
});
|
|
45202
45226
|
|
|
45227
|
+
// ../crypto/dist/telemetry.js
|
|
45228
|
+
function randomHex(byteCount) {
|
|
45229
|
+
const bytes = new Uint8Array(byteCount);
|
|
45230
|
+
crypto.getRandomValues(bytes);
|
|
45231
|
+
let hex = "";
|
|
45232
|
+
for (let i2 = 0; i2 < bytes.length; i2++) {
|
|
45233
|
+
hex += bytes[i2].toString(16).padStart(2, "0");
|
|
45234
|
+
}
|
|
45235
|
+
return hex;
|
|
45236
|
+
}
|
|
45237
|
+
function generateTraceId() {
|
|
45238
|
+
return randomHex(16);
|
|
45239
|
+
}
|
|
45240
|
+
function generateSpanId() {
|
|
45241
|
+
return randomHex(8);
|
|
45242
|
+
}
|
|
45243
|
+
function buildLlmSpan(opts) {
|
|
45244
|
+
const now = Date.now();
|
|
45245
|
+
const attributes = {
|
|
45246
|
+
"ai.agent.llm.model": opts.model,
|
|
45247
|
+
"ai.agent.llm.latency_ms": opts.latencyMs,
|
|
45248
|
+
"ai.agent.llm.tokens_input": opts.tokensInput,
|
|
45249
|
+
"ai.agent.llm.tokens_output": opts.tokensOutput
|
|
45250
|
+
};
|
|
45251
|
+
if (opts.provider !== void 0) {
|
|
45252
|
+
attributes["ai.agent.llm.provider"] = opts.provider;
|
|
45253
|
+
}
|
|
45254
|
+
const isError = opts.status === "error";
|
|
45255
|
+
const status = isError ? { code: 2, ...opts.statusMessage ? { message: opts.statusMessage } : {} } : { code: 0 };
|
|
45256
|
+
return {
|
|
45257
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
45258
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
45259
|
+
parentSpanId: opts.parentSpanId,
|
|
45260
|
+
name: "llm.inference",
|
|
45261
|
+
kind: "internal",
|
|
45262
|
+
startTime: now - opts.latencyMs,
|
|
45263
|
+
endTime: now,
|
|
45264
|
+
attributes,
|
|
45265
|
+
status
|
|
45266
|
+
};
|
|
45267
|
+
}
|
|
45268
|
+
function buildToolSpan(opts) {
|
|
45269
|
+
const now = Date.now();
|
|
45270
|
+
const attributes = {
|
|
45271
|
+
"ai.agent.tool.name": opts.toolName,
|
|
45272
|
+
"ai.agent.tool.latency_ms": opts.latencyMs,
|
|
45273
|
+
"ai.agent.tool.success": opts.success
|
|
45274
|
+
};
|
|
45275
|
+
const status = opts.success ? { code: 0 } : { code: 2, ...opts.errorMessage ? { message: opts.errorMessage } : {} };
|
|
45276
|
+
return {
|
|
45277
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
45278
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
45279
|
+
parentSpanId: opts.parentSpanId,
|
|
45280
|
+
name: "tool.execute",
|
|
45281
|
+
kind: "internal",
|
|
45282
|
+
startTime: now - opts.latencyMs,
|
|
45283
|
+
endTime: now,
|
|
45284
|
+
attributes,
|
|
45285
|
+
status
|
|
45286
|
+
};
|
|
45287
|
+
}
|
|
45288
|
+
function buildErrorSpan(opts) {
|
|
45289
|
+
const now = Date.now();
|
|
45290
|
+
return {
|
|
45291
|
+
traceId: opts.traceId ?? generateTraceId(),
|
|
45292
|
+
spanId: opts.spanId ?? generateSpanId(),
|
|
45293
|
+
parentSpanId: opts.parentSpanId,
|
|
45294
|
+
name: "error",
|
|
45295
|
+
kind: opts.spanKind ?? "internal",
|
|
45296
|
+
startTime: now,
|
|
45297
|
+
endTime: now,
|
|
45298
|
+
attributes: {
|
|
45299
|
+
"ai.agent.error.type": opts.errorType,
|
|
45300
|
+
"ai.agent.error.message": opts.errorMessage
|
|
45301
|
+
},
|
|
45302
|
+
status: { code: 2, message: opts.errorMessage }
|
|
45303
|
+
};
|
|
45304
|
+
}
|
|
45305
|
+
var init_telemetry = __esm({
|
|
45306
|
+
"../crypto/dist/telemetry.js"() {
|
|
45307
|
+
"use strict";
|
|
45308
|
+
}
|
|
45309
|
+
});
|
|
45310
|
+
|
|
45311
|
+
// ../crypto/dist/telemetry-reporter.js
|
|
45312
|
+
function toOtlpAttributes(attrs) {
|
|
45313
|
+
return Object.entries(attrs).map(([key, val]) => {
|
|
45314
|
+
if (typeof val === "string") {
|
|
45315
|
+
return { key, value: { stringValue: val } };
|
|
45316
|
+
}
|
|
45317
|
+
if (typeof val === "boolean") {
|
|
45318
|
+
return { key, value: { boolValue: val } };
|
|
45319
|
+
}
|
|
45320
|
+
if (Number.isInteger(val)) {
|
|
45321
|
+
return { key, value: { intValue: val } };
|
|
45322
|
+
}
|
|
45323
|
+
return { key, value: { doubleValue: val } };
|
|
45324
|
+
});
|
|
45325
|
+
}
|
|
45326
|
+
function spanToOtlp(span) {
|
|
45327
|
+
const otlp = {
|
|
45328
|
+
traceId: span.traceId,
|
|
45329
|
+
spanId: span.spanId,
|
|
45330
|
+
name: span.name,
|
|
45331
|
+
kind: span.kind,
|
|
45332
|
+
startTimeUnixNano: String(span.startTime * 1e6),
|
|
45333
|
+
endTimeUnixNano: String(span.endTime * 1e6),
|
|
45334
|
+
attributes: toOtlpAttributes(span.attributes)
|
|
45335
|
+
};
|
|
45336
|
+
if (span.parentSpanId !== void 0) {
|
|
45337
|
+
otlp.parentSpanId = span.parentSpanId;
|
|
45338
|
+
}
|
|
45339
|
+
if (span.status) {
|
|
45340
|
+
otlp.status = span.status;
|
|
45341
|
+
}
|
|
45342
|
+
if (span.events && span.events.length > 0) {
|
|
45343
|
+
otlp.events = span.events;
|
|
45344
|
+
}
|
|
45345
|
+
return otlp;
|
|
45346
|
+
}
|
|
45347
|
+
var TelemetryReporter;
|
|
45348
|
+
var init_telemetry_reporter = __esm({
|
|
45349
|
+
"../crypto/dist/telemetry-reporter.js"() {
|
|
45350
|
+
"use strict";
|
|
45351
|
+
init_telemetry();
|
|
45352
|
+
TelemetryReporter = class {
|
|
45353
|
+
_apiBase;
|
|
45354
|
+
_hubId;
|
|
45355
|
+
_authHeader;
|
|
45356
|
+
_fetch;
|
|
45357
|
+
_buffer = [];
|
|
45358
|
+
_timer = null;
|
|
45359
|
+
constructor(config) {
|
|
45360
|
+
this._apiBase = config.apiBase.replace(/\/+$/, "");
|
|
45361
|
+
this._hubId = config.hubId;
|
|
45362
|
+
this._authHeader = config.authHeader;
|
|
45363
|
+
this._fetch = config.fetchImpl ?? globalThis.fetch;
|
|
45364
|
+
}
|
|
45365
|
+
/** Number of spans waiting to be flushed. */
|
|
45366
|
+
get pendingCount() {
|
|
45367
|
+
return this._buffer.length;
|
|
45368
|
+
}
|
|
45369
|
+
// -- Report methods ---------------------------------------------------------
|
|
45370
|
+
/** Record an LLM inference call. */
|
|
45371
|
+
reportLlmCall(opts) {
|
|
45372
|
+
this._buffer.push(buildLlmSpan(opts));
|
|
45373
|
+
}
|
|
45374
|
+
/** Record a tool/function invocation. */
|
|
45375
|
+
reportToolCall(opts) {
|
|
45376
|
+
this._buffer.push(buildToolSpan(opts));
|
|
45377
|
+
}
|
|
45378
|
+
/** Record an error event. */
|
|
45379
|
+
reportError(opts) {
|
|
45380
|
+
this._buffer.push(buildErrorSpan(opts));
|
|
45381
|
+
}
|
|
45382
|
+
/** Record an arbitrary pre-built span. */
|
|
45383
|
+
reportCustomSpan(span) {
|
|
45384
|
+
this._buffer.push(span);
|
|
45385
|
+
}
|
|
45386
|
+
// -- Flush ------------------------------------------------------------------
|
|
45387
|
+
/**
|
|
45388
|
+
* POST all buffered spans to the backend ingest endpoint.
|
|
45389
|
+
*
|
|
45390
|
+
* - On success (HTTP 2xx): clears the buffer.
|
|
45391
|
+
* - On failure: keeps spans in the buffer for retry.
|
|
45392
|
+
* - Never throws — telemetry is best-effort.
|
|
45393
|
+
*/
|
|
45394
|
+
async flush() {
|
|
45395
|
+
if (this._buffer.length === 0) {
|
|
45396
|
+
return;
|
|
45397
|
+
}
|
|
45398
|
+
const spans = this._buffer;
|
|
45399
|
+
this._buffer = [];
|
|
45400
|
+
try {
|
|
45401
|
+
const response = await this._fetch(`${this._apiBase}/api/v1/telemetry/ingest`, {
|
|
45402
|
+
method: "POST",
|
|
45403
|
+
headers: {
|
|
45404
|
+
"Content-Type": "application/json",
|
|
45405
|
+
Authorization: this._authHeader
|
|
45406
|
+
},
|
|
45407
|
+
body: JSON.stringify({
|
|
45408
|
+
hub_id: this._hubId,
|
|
45409
|
+
spans: spans.map(spanToOtlp)
|
|
45410
|
+
})
|
|
45411
|
+
});
|
|
45412
|
+
if (!response.ok) {
|
|
45413
|
+
this._buffer = spans.concat(this._buffer);
|
|
45414
|
+
}
|
|
45415
|
+
} catch {
|
|
45416
|
+
this._buffer = spans.concat(this._buffer);
|
|
45417
|
+
}
|
|
45418
|
+
}
|
|
45419
|
+
// -- Auto-flush -------------------------------------------------------------
|
|
45420
|
+
/**
|
|
45421
|
+
* Start a periodic flush timer.
|
|
45422
|
+
* @param intervalMs Flush interval in milliseconds (default 30 000).
|
|
45423
|
+
*/
|
|
45424
|
+
startAutoFlush(intervalMs = 3e4) {
|
|
45425
|
+
this.stopAutoFlush();
|
|
45426
|
+
this._timer = setInterval(() => {
|
|
45427
|
+
void this.flush();
|
|
45428
|
+
}, intervalMs);
|
|
45429
|
+
}
|
|
45430
|
+
/** Stop the periodic flush timer. Safe to call when not started. */
|
|
45431
|
+
stopAutoFlush() {
|
|
45432
|
+
if (this._timer !== null) {
|
|
45433
|
+
clearInterval(this._timer);
|
|
45434
|
+
this._timer = null;
|
|
45435
|
+
}
|
|
45436
|
+
}
|
|
45437
|
+
};
|
|
45438
|
+
}
|
|
45439
|
+
});
|
|
45440
|
+
|
|
45203
45441
|
// ../crypto/dist/index.js
|
|
45204
45442
|
var init_dist = __esm({
|
|
45205
45443
|
async "../crypto/dist/index.js"() {
|
|
@@ -45211,7 +45449,10 @@ var init_dist = __esm({
|
|
|
45211
45449
|
await init_did();
|
|
45212
45450
|
init_scan_engine();
|
|
45213
45451
|
await init_merkle();
|
|
45452
|
+
await init_vc();
|
|
45214
45453
|
await init_transport();
|
|
45454
|
+
init_telemetry();
|
|
45455
|
+
init_telemetry_reporter();
|
|
45215
45456
|
}
|
|
45216
45457
|
});
|
|
45217
45458
|
|
|
@@ -45393,12 +45634,13 @@ var init_channel = __esm({
|
|
|
45393
45634
|
_lastWakeTick = Date.now();
|
|
45394
45635
|
_pendingPollTimer = null;
|
|
45395
45636
|
_syncMessageIds = null;
|
|
45396
|
-
/** Recently handled message IDs via WS — survives reconnects so sync skips them. Max 500. */
|
|
45397
|
-
_recentlyHandledIds = /* @__PURE__ */ new Set();
|
|
45398
45637
|
/** Queued A2A messages for responder channels not yet activated (no first initiator message received). */
|
|
45399
45638
|
_a2aPendingQueue = {};
|
|
45400
45639
|
_scanEngine = null;
|
|
45401
45640
|
_scanRuleSetVersion = 0;
|
|
45641
|
+
_telemetryReporter = null;
|
|
45642
|
+
/** Topic ID from the most recent inbound message — used as fallback for replies. */
|
|
45643
|
+
_lastIncomingTopicId;
|
|
45402
45644
|
// Liveness detection: server sends app-level {"event":"ping"} every 30s.
|
|
45403
45645
|
// We check every 30s; if no data received in 90s (3 missed pings), connection is dead.
|
|
45404
45646
|
static PING_INTERVAL_MS = 3e4;
|
|
@@ -45427,6 +45669,10 @@ var init_channel = __esm({
|
|
|
45427
45669
|
get sessionCount() {
|
|
45428
45670
|
return this._sessions.size;
|
|
45429
45671
|
}
|
|
45672
|
+
/** Returns the TelemetryReporter instance (available after WebSocket connect). */
|
|
45673
|
+
get telemetry() {
|
|
45674
|
+
return this._telemetryReporter;
|
|
45675
|
+
}
|
|
45430
45676
|
async start() {
|
|
45431
45677
|
this._stopped = false;
|
|
45432
45678
|
await libsodium_wrappers_default.ready;
|
|
@@ -45509,7 +45755,7 @@ var init_channel = __esm({
|
|
|
45509
45755
|
if (this._sessions.size === 0) {
|
|
45510
45756
|
throw new Error("No active sessions");
|
|
45511
45757
|
}
|
|
45512
|
-
const topicId = options?.topicId ?? this._persisted?.defaultTopicId;
|
|
45758
|
+
const topicId = options?.topicId ?? this._lastIncomingTopicId ?? this._persisted?.defaultTopicId;
|
|
45513
45759
|
const messageType = options?.messageType ?? "text";
|
|
45514
45760
|
const priority = options?.priority ?? "normal";
|
|
45515
45761
|
const parentSpanId = options?.parentSpanId;
|
|
@@ -45971,6 +46217,11 @@ var init_channel = __esm({
|
|
|
45971
46217
|
clearTimeout(this._reconnectTimer);
|
|
45972
46218
|
this._reconnectTimer = null;
|
|
45973
46219
|
}
|
|
46220
|
+
if (this._telemetryReporter) {
|
|
46221
|
+
this._telemetryReporter.stopAutoFlush();
|
|
46222
|
+
await this._telemetryReporter.flush();
|
|
46223
|
+
this._telemetryReporter = null;
|
|
46224
|
+
}
|
|
45974
46225
|
if (this._ws) {
|
|
45975
46226
|
this._ws.removeAllListeners();
|
|
45976
46227
|
this._ws.close();
|
|
@@ -46494,26 +46745,20 @@ var init_channel = __esm({
|
|
|
46494
46745
|
this._scanEngine = new ScanEngine();
|
|
46495
46746
|
await this._fetchScanRules();
|
|
46496
46747
|
}
|
|
46748
|
+
if (!this._telemetryReporter && this._persisted?.deviceJwt && this._persisted?.hubAddress) {
|
|
46749
|
+
this._telemetryReporter = new TelemetryReporter({
|
|
46750
|
+
apiBase: this.config.apiUrl,
|
|
46751
|
+
hubId: this._persisted.hubAddress,
|
|
46752
|
+
authHeader: `Bearer ${this._persisted.deviceJwt}`
|
|
46753
|
+
});
|
|
46754
|
+
this._telemetryReporter.startAutoFlush(3e4);
|
|
46755
|
+
}
|
|
46497
46756
|
this.emit("ready");
|
|
46498
46757
|
} catch (openErr) {
|
|
46499
46758
|
console.error("[SecureChannel] Error in WS open handler:", openErr);
|
|
46500
46759
|
this.emit("error", openErr);
|
|
46501
46760
|
}
|
|
46502
46761
|
});
|
|
46503
|
-
const _onUnhandledRejection = (reason) => {
|
|
46504
|
-
console.error("[SecureChannel] UNHANDLED REJECTION (would crash process):", reason);
|
|
46505
|
-
};
|
|
46506
|
-
const _onUncaughtException = (err) => {
|
|
46507
|
-
console.error("[SecureChannel] UNCAUGHT EXCEPTION (would crash process):", err);
|
|
46508
|
-
};
|
|
46509
|
-
process.on("unhandledRejection", _onUnhandledRejection);
|
|
46510
|
-
process.on("uncaughtException", _onUncaughtException);
|
|
46511
|
-
ws.on("close", (code, reason) => {
|
|
46512
|
-
const reasonStr = reason?.toString() || "";
|
|
46513
|
-
console.log(`[SecureChannel] WS CLOSED: code=${code} reason=${JSON.stringify(reasonStr)}`);
|
|
46514
|
-
process.removeListener("unhandledRejection", _onUnhandledRejection);
|
|
46515
|
-
process.removeListener("uncaughtException", _onUncaughtException);
|
|
46516
|
-
});
|
|
46517
46762
|
ws.on("message", async (raw) => {
|
|
46518
46763
|
this._lastServerMessage = Date.now();
|
|
46519
46764
|
this._lastWakeTick = Date.now();
|
|
@@ -46533,10 +46778,8 @@ var init_channel = __esm({
|
|
|
46533
46778
|
return;
|
|
46534
46779
|
}
|
|
46535
46780
|
if (data.event === "message") {
|
|
46536
|
-
console.log(`[SecureChannel] \u2190 Direct message received: msg=${data.data?.message_id?.slice(0, 8) ?? "?"} conv=${data.data?.conversation_id?.slice(0, 8) ?? "?"}`);
|
|
46537
46781
|
try {
|
|
46538
46782
|
await this._handleIncomingMessage(data.data);
|
|
46539
|
-
console.log(`[SecureChannel] \u2190 Direct message processed OK: msg=${data.data?.message_id?.slice(0, 8) ?? "?"}`);
|
|
46540
46783
|
} catch (msgErr) {
|
|
46541
46784
|
console.error(
|
|
46542
46785
|
`[SecureChannel] Message handler failed for conv ${data.data?.conversation_id?.slice(0, 8) ?? "?"}...:`,
|
|
@@ -46868,9 +47111,7 @@ var init_channel = __esm({
|
|
|
46868
47111
|
this.emit("error", err);
|
|
46869
47112
|
}
|
|
46870
47113
|
});
|
|
46871
|
-
ws.on("close", (
|
|
46872
|
-
const reasonStr = reason?.toString() || "";
|
|
46873
|
-
console.log(`[SecureChannel] WS close handler: code=${code} reason=${JSON.stringify(reasonStr)}`);
|
|
47114
|
+
ws.on("close", () => {
|
|
46874
47115
|
this._stopPing();
|
|
46875
47116
|
this._stopWakeDetector();
|
|
46876
47117
|
this._stopPendingPoll();
|
|
@@ -46892,11 +47133,6 @@ var init_channel = __esm({
|
|
|
46892
47133
|
if (this._syncMessageIds?.has(msgData.message_id)) {
|
|
46893
47134
|
return;
|
|
46894
47135
|
}
|
|
46895
|
-
this._recentlyHandledIds.add(msgData.message_id);
|
|
46896
|
-
if (this._recentlyHandledIds.size > 500) {
|
|
46897
|
-
const all = [...this._recentlyHandledIds];
|
|
46898
|
-
this._recentlyHandledIds = new Set(all.slice(all.length - 400));
|
|
46899
|
-
}
|
|
46900
47136
|
const convId = msgData.conversation_id;
|
|
46901
47137
|
const session = this._sessions.get(convId);
|
|
46902
47138
|
if (!session) {
|
|
@@ -46909,14 +47145,7 @@ var init_channel = __esm({
|
|
|
46909
47145
|
header_blob: msgData.header_blob,
|
|
46910
47146
|
ciphertext: msgData.ciphertext
|
|
46911
47147
|
});
|
|
46912
|
-
|
|
46913
|
-
try {
|
|
46914
|
-
plaintext = session.ratchet.decrypt(encrypted);
|
|
46915
|
-
} catch (decryptErr) {
|
|
46916
|
-
console.error(`[SecureChannel] Direct message decrypt FAILED for conv ${convId.slice(0, 8)}...: ${String(decryptErr)}`);
|
|
46917
|
-
throw decryptErr;
|
|
46918
|
-
}
|
|
46919
|
-
console.log(`[SecureChannel] Direct message decrypted OK for conv ${convId.slice(0, 8)}...`);
|
|
47148
|
+
const plaintext = session.ratchet.decrypt(encrypted);
|
|
46920
47149
|
this._sendAck(msgData.message_id);
|
|
46921
47150
|
if (!session.activated) {
|
|
46922
47151
|
session.activated = true;
|
|
@@ -46951,6 +47180,7 @@ var init_channel = __esm({
|
|
|
46951
47180
|
}
|
|
46952
47181
|
if (messageType === "message") {
|
|
46953
47182
|
const topicId = msgData.topic_id;
|
|
47183
|
+
this._lastIncomingTopicId = topicId;
|
|
46954
47184
|
let attachData;
|
|
46955
47185
|
if (attachmentInfo) {
|
|
46956
47186
|
try {
|
|
@@ -47009,13 +47239,7 @@ ${messageText}`;
|
|
|
47009
47239
|
Promise.resolve(this.config.onMessage?.(emitText, metadata)).catch((err) => {
|
|
47010
47240
|
console.error("[SecureChannel] onMessage callback error:", err);
|
|
47011
47241
|
});
|
|
47012
|
-
|
|
47013
|
-
try {
|
|
47014
|
-
await this._relaySyncToSiblings(convId, session.ownerDeviceId, messageText, topicId);
|
|
47015
|
-
console.log(`[SecureChannel] Sync relay complete for conv ${convId.slice(0, 8)}...`);
|
|
47016
|
-
} catch (relayErr) {
|
|
47017
|
-
console.error(`[SecureChannel] Sync relay FAILED: ${String(relayErr)}`);
|
|
47018
|
-
}
|
|
47242
|
+
await this._relaySyncToSiblings(convId, session.ownerDeviceId, messageText, topicId);
|
|
47019
47243
|
}
|
|
47020
47244
|
if (this._persisted) {
|
|
47021
47245
|
this._persisted.lastMessageTimestamp = msgData.created_at;
|
|
@@ -47140,29 +47364,22 @@ ${messageText}`;
|
|
|
47140
47364
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
47141
47365
|
topicId
|
|
47142
47366
|
});
|
|
47143
|
-
let relayed = 0;
|
|
47144
47367
|
for (const [siblingConvId, siblingSession] of this._sessions) {
|
|
47145
47368
|
if (siblingConvId === sourceConvId) continue;
|
|
47146
47369
|
if (!siblingSession.activated) continue;
|
|
47147
|
-
|
|
47148
|
-
|
|
47149
|
-
|
|
47150
|
-
|
|
47151
|
-
|
|
47152
|
-
|
|
47153
|
-
|
|
47154
|
-
|
|
47155
|
-
|
|
47156
|
-
|
|
47157
|
-
|
|
47158
|
-
|
|
47159
|
-
);
|
|
47160
|
-
relayed++;
|
|
47161
|
-
} catch (err) {
|
|
47162
|
-
console.error(`[SecureChannel] Sync send failed for sibling ${siblingConvId.slice(0, 8)}...: ${String(err)}`);
|
|
47163
|
-
}
|
|
47370
|
+
const syncEncrypted = siblingSession.ratchet.encrypt(syncPayload);
|
|
47371
|
+
const syncTransport = encryptedMessageToTransport(syncEncrypted);
|
|
47372
|
+
this._ws.send(
|
|
47373
|
+
JSON.stringify({
|
|
47374
|
+
event: "message",
|
|
47375
|
+
data: {
|
|
47376
|
+
conversation_id: siblingConvId,
|
|
47377
|
+
header_blob: syncTransport.header_blob,
|
|
47378
|
+
ciphertext: syncTransport.ciphertext
|
|
47379
|
+
}
|
|
47380
|
+
})
|
|
47381
|
+
);
|
|
47164
47382
|
}
|
|
47165
|
-
console.log(`[SecureChannel] _relaySyncToSiblings: relayed to ${relayed}/${this._sessions.size - 1} siblings`);
|
|
47166
47383
|
}
|
|
47167
47384
|
/**
|
|
47168
47385
|
* Send stored message history to a newly-activated session.
|
|
@@ -47264,12 +47481,52 @@ ${messageText}`;
|
|
|
47264
47481
|
);
|
|
47265
47482
|
return;
|
|
47266
47483
|
}
|
|
47267
|
-
|
|
47484
|
+
let session = this._sessions.get(convId);
|
|
47268
47485
|
if (!session) {
|
|
47269
47486
|
console.warn(
|
|
47270
|
-
`[SecureChannel] No session for room conv ${convId.slice(0, 8)}...,
|
|
47487
|
+
`[SecureChannel] No session for room conv ${convId.slice(0, 8)}..., fetching room data`
|
|
47271
47488
|
);
|
|
47272
|
-
|
|
47489
|
+
try {
|
|
47490
|
+
const roomRes = await fetch(
|
|
47491
|
+
`${this.config.apiUrl}/api/v1/rooms/${msgData.room_id}`,
|
|
47492
|
+
{
|
|
47493
|
+
headers: {
|
|
47494
|
+
Authorization: `Bearer ${this._persisted.deviceJwt}`
|
|
47495
|
+
}
|
|
47496
|
+
}
|
|
47497
|
+
);
|
|
47498
|
+
if (roomRes.ok) {
|
|
47499
|
+
const roomData = await roomRes.json();
|
|
47500
|
+
await this.joinRoom({
|
|
47501
|
+
roomId: roomData.id,
|
|
47502
|
+
name: roomData.name,
|
|
47503
|
+
members: (roomData.members || []).map((m2) => ({
|
|
47504
|
+
deviceId: m2.device_id,
|
|
47505
|
+
entityType: m2.entity_type,
|
|
47506
|
+
displayName: m2.display_name,
|
|
47507
|
+
identityPublicKey: m2.identity_public_key,
|
|
47508
|
+
ephemeralPublicKey: m2.ephemeral_public_key
|
|
47509
|
+
})),
|
|
47510
|
+
conversations: (roomData.conversations || []).map((c2) => ({
|
|
47511
|
+
id: c2.id,
|
|
47512
|
+
participantA: c2.participant_a,
|
|
47513
|
+
participantB: c2.participant_b
|
|
47514
|
+
}))
|
|
47515
|
+
});
|
|
47516
|
+
session = this._sessions.get(convId);
|
|
47517
|
+
}
|
|
47518
|
+
} catch (fetchErr) {
|
|
47519
|
+
console.error(
|
|
47520
|
+
`[SecureChannel] Failed to fetch room data for ${msgData.room_id}:`,
|
|
47521
|
+
fetchErr
|
|
47522
|
+
);
|
|
47523
|
+
}
|
|
47524
|
+
if (!session) {
|
|
47525
|
+
console.warn(
|
|
47526
|
+
`[SecureChannel] Still no session for room conv ${convId.slice(0, 8)}... after refresh, skipping`
|
|
47527
|
+
);
|
|
47528
|
+
return;
|
|
47529
|
+
}
|
|
47273
47530
|
}
|
|
47274
47531
|
const encrypted = transportToEncryptedMessage({
|
|
47275
47532
|
header_blob: msgData.header_blob,
|
|
@@ -47399,7 +47656,6 @@ ${messageText}`;
|
|
|
47399
47656
|
const PAGE_SIZE = 200;
|
|
47400
47657
|
let since = this._persisted.lastMessageTimestamp;
|
|
47401
47658
|
let totalProcessed = 0;
|
|
47402
|
-
let totalSkipped = 0;
|
|
47403
47659
|
try {
|
|
47404
47660
|
for (let page = 0; page < MAX_PAGES; page++) {
|
|
47405
47661
|
const url = `${this.config.apiUrl}/api/v1/devices/${this._deviceId}/messages?since=${encodeURIComponent(since)}&limit=${PAGE_SIZE}`;
|
|
@@ -47409,24 +47665,15 @@ ${messageText}`;
|
|
|
47409
47665
|
if (!res.ok) break;
|
|
47410
47666
|
const messages = await res.json();
|
|
47411
47667
|
if (messages.length === 0) break;
|
|
47412
|
-
console.log(`[SecureChannel] Sync page ${page}: ${messages.length} messages since ${since}`);
|
|
47413
47668
|
for (const msg of messages) {
|
|
47414
47669
|
if (msg.sender_device_id === this._deviceId) continue;
|
|
47415
47670
|
if (this._syncMessageIds.has(msg.id)) continue;
|
|
47416
47671
|
this._syncMessageIds.add(msg.id);
|
|
47417
|
-
if (this._recentlyHandledIds.has(msg.id)) {
|
|
47418
|
-
this._persisted.lastMessageTimestamp = msg.created_at;
|
|
47419
|
-
since = msg.created_at;
|
|
47420
|
-
totalSkipped++;
|
|
47421
|
-
continue;
|
|
47422
|
-
}
|
|
47423
47672
|
const session = this._sessions.get(msg.conversation_id);
|
|
47424
47673
|
if (!session) {
|
|
47425
47674
|
console.warn(
|
|
47426
47675
|
`[SecureChannel] No session for conversation ${msg.conversation_id} during sync, skipping`
|
|
47427
47676
|
);
|
|
47428
|
-
this._persisted.lastMessageTimestamp = msg.created_at;
|
|
47429
|
-
since = msg.created_at;
|
|
47430
47677
|
continue;
|
|
47431
47678
|
}
|
|
47432
47679
|
try {
|
|
@@ -47460,6 +47707,9 @@ ${messageText}`;
|
|
|
47460
47707
|
topicId
|
|
47461
47708
|
};
|
|
47462
47709
|
this.emit("message", messageText, metadata);
|
|
47710
|
+
Promise.resolve(this.config.onMessage?.(messageText, metadata)).catch((err) => {
|
|
47711
|
+
console.error("[SecureChannel] onMessage callback error:", err);
|
|
47712
|
+
});
|
|
47463
47713
|
}
|
|
47464
47714
|
this._persisted.lastMessageTimestamp = msg.created_at;
|
|
47465
47715
|
since = msg.created_at;
|
|
@@ -47476,15 +47726,10 @@ ${messageText}`;
|
|
|
47476
47726
|
await this._persistState();
|
|
47477
47727
|
if (messages.length < PAGE_SIZE) break;
|
|
47478
47728
|
}
|
|
47479
|
-
if (totalProcessed > 0
|
|
47480
|
-
console.log(`[SecureChannel]
|
|
47481
|
-
}
|
|
47482
|
-
} catch (outerErr) {
|
|
47483
|
-
console.warn(`[SecureChannel] Sync interrupted: ${String(outerErr)}`);
|
|
47484
|
-
try {
|
|
47485
|
-
await this._persistState();
|
|
47486
|
-
} catch {
|
|
47729
|
+
if (totalProcessed > 0) {
|
|
47730
|
+
console.log(`[SecureChannel] Synced ${totalProcessed} missed messages`);
|
|
47487
47731
|
}
|
|
47732
|
+
} catch {
|
|
47488
47733
|
}
|
|
47489
47734
|
this._syncMessageIds = null;
|
|
47490
47735
|
}
|