@agentvault/secure-channel 0.6.25 → 0.7.0

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, DecisionOption, DecisionRequest, DecisionResponse, ContextRef, HeartbeatStatus, StatusAlert, RoomInfo, RoomMemberInfo, RoomConversationInfo, RoomState, } from "./types.js";
2
+ export type { SecureChannelConfig, ChannelState, MessageMetadata, AttachmentData, PersistedState, LegacyPersistedState, DeviceSession, HistoryEntry, SendOptions, DecisionOption, DecisionRequest, DecisionResponse, ContextRef, HeartbeatStatus, StatusAlert, RoomInfo, RoomMemberInfo, RoomConversationInfo, RoomState, A2AChannel, A2AMessage, } 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,EACX,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,eAAe,EACf,WAAW,EACX,QAAQ,EACR,cAAc,EACd,oBAAoB,EACpB,SAAS,GACV,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,EACX,QAAQ,EACR,cAAc,EACd,oBAAoB,EACpB,SAAS,EACT,UAAU,EACV,UAAU,GACX,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
@@ -45234,20 +45234,24 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
45234
45234
  topicId
45235
45235
  };
45236
45236
  if (this._state === "ready" && this._ws) {
45237
+ const payload = {
45238
+ conversation_id: msg.convId,
45239
+ header_blob: msg.headerBlob,
45240
+ ciphertext: msg.ciphertext,
45241
+ message_group_id: msg.messageGroupId,
45242
+ topic_id: msg.topicId,
45243
+ message_type: messageType,
45244
+ priority,
45245
+ parent_span_id: parentSpanId,
45246
+ metadata: envelopeMetadata
45247
+ };
45248
+ if (this._persisted?.hubAddress) {
45249
+ payload.hub_address = this._persisted.hubAddress;
45250
+ }
45237
45251
  this._ws.send(
45238
45252
  JSON.stringify({
45239
45253
  event: "message",
45240
- data: {
45241
- conversation_id: msg.convId,
45242
- header_blob: msg.headerBlob,
45243
- ciphertext: msg.ciphertext,
45244
- message_group_id: msg.messageGroupId,
45245
- topic_id: msg.topicId,
45246
- message_type: messageType,
45247
- priority,
45248
- parent_span_id: parentSpanId,
45249
- metadata: envelopeMetadata
45250
- }
45254
+ data: payload
45251
45255
  })
45252
45256
  );
45253
45257
  } else {
@@ -45777,6 +45781,130 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
45777
45781
  await this._persistState();
45778
45782
  return topics;
45779
45783
  }
45784
+ // --- A2A Channel methods (agent-to-agent communication) ---
45785
+ /**
45786
+ * Request a new A2A channel with another agent by their hub address.
45787
+ * Returns the channel_id from the server response.
45788
+ */
45789
+ async requestA2AChannel(responderHubAddress) {
45790
+ if (!this._persisted?.hubAddress) {
45791
+ throw new Error("This agent does not have a hub address assigned");
45792
+ }
45793
+ if (!this._deviceJwt) {
45794
+ throw new Error("Channel not authenticated");
45795
+ }
45796
+ const res = await fetch(`${this.config.apiUrl}/api/v1/a2a/channels/request`, {
45797
+ method: "POST",
45798
+ headers: {
45799
+ "Content-Type": "application/json",
45800
+ Authorization: `Bearer ${this._deviceJwt}`
45801
+ },
45802
+ body: JSON.stringify({
45803
+ initiator_hub_address: this._persisted.hubAddress,
45804
+ responder_hub_address: responderHubAddress
45805
+ })
45806
+ });
45807
+ if (!res.ok) {
45808
+ const detail = await res.text();
45809
+ throw new Error(`A2A channel request failed (${res.status}): ${detail}`);
45810
+ }
45811
+ const resp = await res.json();
45812
+ const channelId = resp.channel_id || resp.id;
45813
+ if (!this._persisted.a2aChannels) {
45814
+ this._persisted.a2aChannels = {};
45815
+ }
45816
+ this._persisted.a2aChannels[channelId] = {
45817
+ channelId,
45818
+ hubAddress: responderHubAddress,
45819
+ conversationId: resp.conversation_id || ""
45820
+ };
45821
+ await this._persistState();
45822
+ return channelId;
45823
+ }
45824
+ /**
45825
+ * Send a message to another agent via an active A2A channel.
45826
+ * Looks up the A2A conversation by hub address and sends via WS.
45827
+ *
45828
+ * NOTE: Currently sends plaintext over the WS (server-side relay).
45829
+ * Full E2E encryption (X3DH + Double Ratchet per A2A session) will be
45830
+ * added when the A2A ratchet activation flow is implemented.
45831
+ */
45832
+ async sendToAgent(hubAddress, text, opts) {
45833
+ if (!this._persisted?.a2aChannels) {
45834
+ throw new Error("No A2A channels established");
45835
+ }
45836
+ const channelEntry = Object.values(this._persisted.a2aChannels).find(
45837
+ (ch) => ch.hubAddress === hubAddress
45838
+ );
45839
+ if (!channelEntry) {
45840
+ throw new Error(`No A2A channel found for hub address: ${hubAddress}`);
45841
+ }
45842
+ if (!channelEntry.conversationId) {
45843
+ throw new Error(`A2A channel ${channelEntry.channelId} does not have a conversation yet (not activated)`);
45844
+ }
45845
+ if (this._state !== "ready" || !this._ws) {
45846
+ throw new Error("Channel is not connected");
45847
+ }
45848
+ const payload = {
45849
+ conversation_id: channelEntry.conversationId,
45850
+ plaintext: text,
45851
+ message_type: "a2a",
45852
+ parent_span_id: opts?.parentSpanId
45853
+ };
45854
+ if (this._persisted.hubAddress) {
45855
+ payload.hub_address = this._persisted.hubAddress;
45856
+ }
45857
+ this._ws.send(
45858
+ JSON.stringify({
45859
+ event: "a2a_message",
45860
+ data: payload
45861
+ })
45862
+ );
45863
+ }
45864
+ /**
45865
+ * List all A2A channels for this agent.
45866
+ * Fetches from the server and updates local persisted state.
45867
+ */
45868
+ async listA2AChannels() {
45869
+ if (!this._deviceJwt) {
45870
+ throw new Error("Channel not authenticated");
45871
+ }
45872
+ const res = await fetch(`${this.config.apiUrl}/api/v1/a2a/channels`, {
45873
+ headers: {
45874
+ Authorization: `Bearer ${this._deviceJwt}`
45875
+ }
45876
+ });
45877
+ if (!res.ok) {
45878
+ const detail = await res.text();
45879
+ throw new Error(`List A2A channels failed (${res.status}): ${detail}`);
45880
+ }
45881
+ const resp = await res.json();
45882
+ const channels = resp.map((ch) => ({
45883
+ channelId: ch.channel_id || ch.id,
45884
+ initiatorHubAddress: ch.initiator_hub_address,
45885
+ responderHubAddress: ch.responder_hub_address,
45886
+ conversationId: ch.conversation_id,
45887
+ status: ch.status,
45888
+ createdAt: ch.created_at
45889
+ }));
45890
+ if (this._persisted) {
45891
+ if (!this._persisted.a2aChannels) {
45892
+ this._persisted.a2aChannels = {};
45893
+ }
45894
+ for (const ch of channels) {
45895
+ if (ch.status === "active" || ch.status === "approved") {
45896
+ const otherAddress = ch.initiatorHubAddress === this._persisted.hubAddress ? ch.responderHubAddress : ch.initiatorHubAddress;
45897
+ this._persisted.a2aChannels[ch.channelId] = {
45898
+ channelId: ch.channelId,
45899
+ hubAddress: otherAddress,
45900
+ conversationId: ch.conversationId || ""
45901
+ };
45902
+ }
45903
+ }
45904
+ await this._persistState();
45905
+ }
45906
+ return channels;
45907
+ }
45780
45908
  // --- Internal lifecycle ---
45781
45909
  async _enroll() {
45782
45910
  this._setState("enrolling");
@@ -46029,6 +46157,62 @@ var SecureChannel = class _SecureChannel extends EventEmitter {
46029
46157
  if (data.event === "policy_rejected") {
46030
46158
  this.emit("policy_rejected", data.data);
46031
46159
  }
46160
+ if (data.event === "hub_identity_assigned") {
46161
+ if (this._persisted) {
46162
+ this._persisted.hubAddress = data.data.hub_address;
46163
+ this._persistState();
46164
+ }
46165
+ this.emit("hub_identity_assigned", data.data);
46166
+ }
46167
+ if (data.event === "hub_identity_removed") {
46168
+ if (this._persisted) {
46169
+ delete this._persisted.hubAddress;
46170
+ this._persistState();
46171
+ }
46172
+ this.emit("hub_identity_removed", data.data);
46173
+ }
46174
+ if (data.event === "a2a_channel_approved") {
46175
+ const channelData = data.data || data;
46176
+ const channelId = channelData.channel_id;
46177
+ const convId = channelData.conversation_id;
46178
+ if (this._persisted && convId) {
46179
+ if (!this._persisted.a2aChannels) this._persisted.a2aChannels = {};
46180
+ this._persisted.a2aChannels[channelId] = {
46181
+ channelId,
46182
+ hubAddress: "",
46183
+ conversationId: convId
46184
+ };
46185
+ await this._persistState();
46186
+ }
46187
+ this.emit("a2a_channel_approved", channelData);
46188
+ }
46189
+ if (data.event === "a2a_channel_rejected") {
46190
+ this.emit("a2a_channel_rejected", data.data || data);
46191
+ }
46192
+ if (data.event === "a2a_channel_revoked") {
46193
+ const channelData = data.data || data;
46194
+ const channelId = channelData.channel_id;
46195
+ if (this._persisted?.a2aChannels?.[channelId]) {
46196
+ delete this._persisted.a2aChannels[channelId];
46197
+ await this._persistState();
46198
+ }
46199
+ this.emit("a2a_channel_revoked", channelData);
46200
+ }
46201
+ if (data.event === "a2a_message") {
46202
+ const msgData = data.data || data;
46203
+ const a2aMsg = {
46204
+ text: msgData.plaintext || msgData.text,
46205
+ fromHubAddress: msgData.from_hub_address || msgData.hub_address || "",
46206
+ channelId: msgData.channel_id || "",
46207
+ conversationId: msgData.conversation_id || "",
46208
+ parentSpanId: msgData.parent_span_id,
46209
+ timestamp: msgData.timestamp || (/* @__PURE__ */ new Date()).toISOString()
46210
+ };
46211
+ this.emit("a2a_message", a2aMsg);
46212
+ if (this.config.onA2AMessage) {
46213
+ this.config.onA2AMessage(a2aMsg);
46214
+ }
46215
+ }
46032
46216
  } catch (err) {
46033
46217
  this.emit("error", err);
46034
46218
  }