@agentvault/secure-channel 0.6.19 → 0.6.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/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { SecureChannel } from "./channel.js";
2
- export type { SecureChannelConfig, ChannelState, MessageMetadata, AttachmentData, PersistedState, LegacyPersistedState, DeviceSession, HistoryEntry, SendOptions, } from "./types.js";
2
+ export type { SecureChannelConfig, ChannelState, MessageMetadata, AttachmentData, PersistedState, LegacyPersistedState, DeviceSession, HistoryEntry, SendOptions, DecisionOption, DecisionRequest, DecisionResponse, ContextRef, HeartbeatStatus, StatusAlert, } from "./types.js";
3
3
  export { agentVaultPlugin, setOcRuntime, getActiveChannel } from "./openclaw-plugin.js";
4
4
  export declare const VERSION = "0.6.13";
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EACV,mBAAmB,EACnB,YAAY,EACZ,eAAe,EACf,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,YAAY,EACZ,WAAW,GACZ,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExF,eAAO,MAAM,OAAO,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EACV,mBAAmB,EACnB,YAAY,EACZ,eAAe,EACf,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,YAAY,EACZ,WAAW,EACX,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,WAAW,GACZ,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExF,eAAO,MAAM,OAAO,WAAW,CAAC"}
package/dist/index.js CHANGED
@@ -45120,6 +45120,9 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
45120
45120
  _persisted = null;
45121
45121
  _httpServer = null;
45122
45122
  _pollFallbackTimer = null;
45123
+ _heartbeatTimer = null;
45124
+ _heartbeatCallback = null;
45125
+ _heartbeatIntervalSeconds = 0;
45123
45126
  _syncMessageIds = null;
45124
45127
  // Liveness detection: server sends app-level {"event":"ping"} every 30s.
45125
45128
  // We check every 30s; if no data received in 90s (3 missed pings), connection is dead.
@@ -45276,8 +45279,139 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
45276
45279
  );
45277
45280
  }
45278
45281
  }
45282
+ /**
45283
+ * Send a decision request to the owner.
45284
+ * Builds a structured envelope with decision metadata and sends it
45285
+ * as a high-priority message. Returns the generated decision_id.
45286
+ */
45287
+ async sendDecisionRequest(request) {
45288
+ const decision_id = `dec_${randomUUID().replace(/-/g, "").slice(0, 16)}`;
45289
+ const payload = JSON.stringify({
45290
+ type: "message",
45291
+ text: `\u{1F4CB} ${request.title}`,
45292
+ decision: {
45293
+ decision_id,
45294
+ ...request
45295
+ }
45296
+ });
45297
+ await this.send(payload, {
45298
+ messageType: "decision_request",
45299
+ priority: "high",
45300
+ metadata: {
45301
+ decision_id,
45302
+ title: request.title,
45303
+ description: request.description,
45304
+ options: request.options,
45305
+ context_refs: request.context_refs,
45306
+ deadline: request.deadline,
45307
+ auto_action: request.auto_action
45308
+ }
45309
+ });
45310
+ return decision_id;
45311
+ }
45312
+ /**
45313
+ * Wait for a decision response matching the given decisionId.
45314
+ * Listens on the "message" event for messages where
45315
+ * metadata.messageType === "decision_response" and the parsed plaintext
45316
+ * contains a matching decision.decision_id.
45317
+ * Optional timeout rejects with an Error.
45318
+ */
45319
+ waitForDecision(decisionId, timeoutMs) {
45320
+ return new Promise((resolve2, reject) => {
45321
+ let timer = null;
45322
+ const handler = (plaintext, metadata) => {
45323
+ if (metadata.messageType !== "decision_response") return;
45324
+ try {
45325
+ const parsed = JSON.parse(plaintext);
45326
+ if (parsed.decision?.decision_id === decisionId) {
45327
+ if (timer) clearTimeout(timer);
45328
+ this.removeListener("message", handler);
45329
+ resolve2({
45330
+ decision_id: parsed.decision.decision_id,
45331
+ selected_option_id: parsed.decision.selected_option_id,
45332
+ resolved_at: parsed.decision.resolved_at
45333
+ });
45334
+ }
45335
+ } catch {
45336
+ }
45337
+ };
45338
+ this.on("message", handler);
45339
+ if (timeoutMs !== void 0) {
45340
+ timer = setTimeout(() => {
45341
+ this.removeListener("message", handler);
45342
+ reject(new Error(`Decision ${decisionId} timed out after ${timeoutMs}ms`));
45343
+ }, timeoutMs);
45344
+ }
45345
+ });
45346
+ }
45347
+ startHeartbeat(intervalSeconds, statusCallback) {
45348
+ this.stopHeartbeat();
45349
+ this._heartbeatCallback = statusCallback;
45350
+ this._heartbeatIntervalSeconds = intervalSeconds;
45351
+ this._sendHeartbeat();
45352
+ this._heartbeatTimer = setInterval(() => {
45353
+ this._sendHeartbeat();
45354
+ }, intervalSeconds * 1e3);
45355
+ }
45356
+ async stopHeartbeat() {
45357
+ if (this._heartbeatTimer) {
45358
+ clearInterval(this._heartbeatTimer);
45359
+ this._heartbeatTimer = null;
45360
+ }
45361
+ if (this._heartbeatCallback && this._state === "ready") {
45362
+ try {
45363
+ await this.send(
45364
+ JSON.stringify({
45365
+ agent_status: "shutting_down",
45366
+ current_task: "",
45367
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
45368
+ }),
45369
+ {
45370
+ messageType: "heartbeat",
45371
+ metadata: { next_heartbeat_seconds: this._heartbeatIntervalSeconds }
45372
+ }
45373
+ );
45374
+ } catch {
45375
+ }
45376
+ }
45377
+ this._heartbeatCallback = null;
45378
+ }
45379
+ async sendStatusAlert(alert) {
45380
+ const priority = alert.severity === "error" || alert.severity === "critical" ? "high" : "normal";
45381
+ await this.send(
45382
+ JSON.stringify({
45383
+ title: alert.title,
45384
+ message: alert.message,
45385
+ severity: alert.severity,
45386
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
45387
+ }),
45388
+ {
45389
+ messageType: "status_alert",
45390
+ priority,
45391
+ metadata: { severity: alert.severity }
45392
+ }
45393
+ );
45394
+ }
45395
+ _sendHeartbeat() {
45396
+ if (this._state !== "ready" || !this._heartbeatCallback) return;
45397
+ const status = this._heartbeatCallback();
45398
+ this.send(
45399
+ JSON.stringify({
45400
+ agent_status: status.agent_status,
45401
+ current_task: status.current_task,
45402
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
45403
+ }),
45404
+ {
45405
+ messageType: "heartbeat",
45406
+ metadata: { next_heartbeat_seconds: this._heartbeatIntervalSeconds }
45407
+ }
45408
+ ).catch((err) => {
45409
+ this.emit("error", new Error(`Heartbeat send failed: ${err}`));
45410
+ });
45411
+ }
45279
45412
  async stop() {
45280
45413
  this._stopped = true;
45414
+ await this.stopHeartbeat();
45281
45415
  this._flushAcks();
45282
45416
  this._stopPing();
45283
45417
  this._stopPollFallback();