@masons/agent-network 0.6.15 → 0.6.17

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.
Files changed (48) hide show
  1. package/dist/_vendor/runtime-adapter-client/conformance.d.ts +8 -0
  2. package/dist/_vendor/runtime-adapter-client/conformance.d.ts.map +1 -0
  3. package/dist/_vendor/runtime-adapter-client/conformance.js +75 -0
  4. package/dist/_vendor/runtime-adapter-client/icm.d.ts +6 -0
  5. package/dist/_vendor/runtime-adapter-client/icm.d.ts.map +1 -0
  6. package/dist/_vendor/runtime-adapter-client/icm.js +86 -0
  7. package/dist/_vendor/runtime-adapter-client/index.d.ts +7 -0
  8. package/dist/_vendor/runtime-adapter-client/index.d.ts.map +1 -0
  9. package/dist/_vendor/runtime-adapter-client/index.js +6 -0
  10. package/dist/_vendor/runtime-adapter-client/runtime-adapter-api.d.ts +301 -0
  11. package/dist/_vendor/runtime-adapter-client/runtime-adapter-api.d.ts.map +1 -0
  12. package/dist/_vendor/runtime-adapter-client/runtime-adapter-api.js +3214 -0
  13. package/dist/_vendor/runtime-adapter-client/send-admission.d.ts +89 -0
  14. package/dist/_vendor/runtime-adapter-client/send-admission.d.ts.map +1 -0
  15. package/dist/_vendor/runtime-adapter-client/send-admission.js +169 -0
  16. package/dist/_vendor/runtime-adapter-client/types.d.ts +659 -0
  17. package/dist/_vendor/runtime-adapter-client/types.d.ts.map +1 -0
  18. package/dist/_vendor/runtime-adapter-client/types.js +33 -0
  19. package/dist/_vendor/runtime-adapter-client/work-target.d.ts +5 -0
  20. package/dist/_vendor/runtime-adapter-client/work-target.d.ts.map +1 -0
  21. package/dist/_vendor/runtime-adapter-client/work-target.js +47 -0
  22. package/dist/channel-setup.d.ts.map +1 -1
  23. package/dist/channel-setup.js +0 -1
  24. package/dist/channel.d.ts.map +1 -1
  25. package/dist/channel.js +105 -29
  26. package/dist/cli-setup.d.ts.map +1 -1
  27. package/dist/cli-setup.js +0 -1
  28. package/dist/connector-client.d.ts +2 -1
  29. package/dist/connector-client.d.ts.map +1 -1
  30. package/dist/connector-client.js +6 -1
  31. package/dist/handoff.d.ts +0 -2
  32. package/dist/handoff.d.ts.map +1 -1
  33. package/dist/handoff.js +0 -3
  34. package/dist/plugin.d.ts +1 -1
  35. package/dist/plugin.d.ts.map +1 -1
  36. package/dist/plugin.js +15 -8
  37. package/dist/services-retained-recipient.d.ts +58 -0
  38. package/dist/services-retained-recipient.d.ts.map +1 -0
  39. package/dist/services-retained-recipient.js +324 -0
  40. package/dist/turn-context.d.ts +2 -0
  41. package/dist/turn-context.d.ts.map +1 -1
  42. package/dist/turn-context.js +9 -0
  43. package/dist/types.d.ts +5 -1
  44. package/dist/types.d.ts.map +1 -1
  45. package/dist/types.js +3 -0
  46. package/dist/version.d.ts +1 -1
  47. package/dist/version.js +1 -1
  48. package/package.json +3 -3
@@ -0,0 +1,33 @@
1
+ export const RUNTIME_ASSIGNMENT_FAILURE_CATEGORIES = [
2
+ "assignment_in_progress",
3
+ "target_unavailable_before_acceptance",
4
+ "acceptance_rejected",
5
+ "processing_failed_or_expired",
6
+ "reply_handle_stale",
7
+ ];
8
+ export const RUNTIME_PROCESSING_STATES = [
9
+ "assigned_to_runtime_target",
10
+ "adapter_accepted",
11
+ "processing_started",
12
+ "reply_requested",
13
+ "reply_emitted",
14
+ "processing_failed",
15
+ "waiting_for_runtime_capability",
16
+ "target_lost_before_acceptance",
17
+ "processing_interrupted",
18
+ "expired",
19
+ ];
20
+ export const ADAPTER_RUNTIME_PROCESSING_STATES = [
21
+ "adapter_accepted",
22
+ "processing_started",
23
+ "processing_failed",
24
+ "waiting_for_runtime_capability",
25
+ "target_lost_before_acceptance",
26
+ "processing_interrupted",
27
+ "expired",
28
+ ];
29
+ export const SYSTEM_RUNTIME_PROCESSING_STATES = [
30
+ "assigned_to_runtime_target",
31
+ "reply_requested",
32
+ "reply_emitted",
33
+ ];
@@ -0,0 +1,5 @@
1
+ import type { RuntimeWorkTargetRef } from "./types.js";
2
+ export declare function parseRuntimeWorkTargetRef(value: unknown): RuntimeWorkTargetRef | null;
3
+ export declare function isRuntimeWorkTargetRef(value: unknown): value is RuntimeWorkTargetRef;
4
+ export declare function sameRuntimeWorkTargetRef(left: RuntimeWorkTargetRef, right: RuntimeWorkTargetRef): boolean;
5
+ //# sourceMappingURL=work-target.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-target.d.ts","sourceRoot":"","sources":["../../../src/_vendor/runtime-adapter-client/work-target.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,GACb,oBAAoB,GAAG,IAAI,CAiC7B;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,oBAAoB,CAE/B;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,oBAAoB,EAC1B,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAeT"}
@@ -0,0 +1,47 @@
1
+ export function parseRuntimeWorkTargetRef(value) {
2
+ if (!value || typeof value !== "object" || Array.isArray(value))
3
+ return null;
4
+ const raw = value;
5
+ if (raw.kind !== "projection_endpoint" ||
6
+ typeof raw.projection_endpoint_id !== "string" ||
7
+ raw.projection_endpoint_id.trim().length === 0) {
8
+ return null;
9
+ }
10
+ const projectionEndpointId = raw.projection_endpoint_id.trim();
11
+ if (raw.background_exchange_mode === "resident_endpoint") {
12
+ if (raw.runtime_session_id !== undefined)
13
+ return null;
14
+ return {
15
+ kind: "projection_endpoint",
16
+ projection_endpoint_id: projectionEndpointId,
17
+ background_exchange_mode: "resident_endpoint",
18
+ };
19
+ }
20
+ if ((raw.background_exchange_mode === "adapter_managed_turn" ||
21
+ raw.background_exchange_mode === "session_attached_pull") &&
22
+ typeof raw.runtime_session_id === "string" &&
23
+ raw.runtime_session_id.trim().length > 0) {
24
+ return {
25
+ kind: "projection_endpoint",
26
+ projection_endpoint_id: projectionEndpointId,
27
+ runtime_session_id: raw.runtime_session_id.trim(),
28
+ background_exchange_mode: raw.background_exchange_mode,
29
+ };
30
+ }
31
+ return null;
32
+ }
33
+ export function isRuntimeWorkTargetRef(value) {
34
+ return parseRuntimeWorkTargetRef(value) !== null;
35
+ }
36
+ export function sameRuntimeWorkTargetRef(left, right) {
37
+ if (left.kind !== right.kind ||
38
+ left.projection_endpoint_id !== right.projection_endpoint_id ||
39
+ left.background_exchange_mode !== right.background_exchange_mode) {
40
+ return false;
41
+ }
42
+ if (left.background_exchange_mode === "resident_endpoint") {
43
+ return right.background_exchange_mode === "resident_endpoint";
44
+ }
45
+ return (right.background_exchange_mode === left.background_exchange_mode &&
46
+ left.runtime_session_id === right.runtime_session_id);
47
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"channel-setup.d.ts","sourceRoot":"","sources":["../src/channel-setup.ts"],"names":[],"mappings":"AAgBA,UAAU,wBAAwB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IAMnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAuBD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAKD,wBAAgB,6BAA6B,IAAI,wBAAwB,CAKxE;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CAsC7B;AAED,wBAAgB,qBAAqB,IAAI,kBAAkB,GAAG,IAAI,CAejE;AAED,wBAAgB,yBAAyB,IAAI,kBAAkB,GAAG,IAAI,CAMrE;AAkED,wBAAgB,4BAA4B,IAAI,IAAI,CAGnD;AAED,eAAO,MAAM,oBAAoB,QAAqB,CAAC"}
1
+ {"version":3,"file":"channel-setup.d.ts","sourceRoot":"","sources":["../src/channel-setup.ts"],"names":[],"mappings":"AAgBA,UAAU,wBAAwB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IAMnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAuBD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAKD,wBAAgB,6BAA6B,IAAI,wBAAwB,CAKxE;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CAqC7B;AAED,wBAAgB,qBAAqB,IAAI,kBAAkB,GAAG,IAAI,CAejE;AAED,wBAAgB,yBAAyB,IAAI,kBAAkB,GAAG,IAAI,CAMrE;AAkED,wBAAgB,4BAA4B,IAAI,IAAI,CAGnD;AAED,eAAO,MAAM,oBAAoB,QAAqB,CAAC"}
@@ -29,7 +29,6 @@ export async function startOrGetChannelSetup(options) {
29
29
  const session = await beginBridgeHandoff({
30
30
  apiHost: options.apiHost,
31
31
  idpBaseUrl: options.idpBaseUrl,
32
- sessionTopology: "single_session",
33
32
  });
34
33
  const record = {
35
34
  session,
@@ -1 +1 @@
1
- {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EAEd,MAAM,kCAAkC,CAAC;AAY1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AA2C9D,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,IAAI,CAEvD;AAOD,wBAAgB,2BAA2B,IAAI,OAAO,CAIrD;AAGD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAE/D;AAaD,iBAAS,iCAAiC,CACxC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA6BzB;AAED,eAAO,MAAM,4CAA4C,0CACtB,CAAC;AA0dpC,eAAO,MAAM,mBAAmB,EAAE,aAAa,CAAC,mBAAmB,CA4NlE,CAAC"}
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EAEd,MAAM,kCAAkC,CAAC;AAa1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAkD9D,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,IAAI,CAEvD;AAOD,wBAAgB,2BAA2B,IAAI,OAAO,CAIrD;AAGD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAE/D;AAaD,iBAAS,iCAAiC,CACxC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA6BzB;AAED,eAAO,MAAM,4CAA4C,0CACtB,CAAC;AA+gBpC,eAAO,MAAM,mBAAmB,EAAE,aAAa,CAAC,mBAAmB,CAiRlE,CAAC"}
package/dist/channel.js CHANGED
@@ -1,15 +1,17 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import createDebug from "debug";
3
- import { clearConnectorClient, clearConversationManager, extractNetworkConfig, getDmScope, initConnectorClient, initConversationManager, initToolConfig, isIdentityLinksConfigured, requirePluginRuntime, } from "./config.js";
3
+ import { clearConnectorClient, clearConversationManager, extractNetworkConfig, getDmScope, initConnectorClient, initConversationManager, initToolConfig, isIdentityLinksConfigured, requirePlatformConfig, requirePluginRuntime, } from "./config.js";
4
4
  import { ConnectorClient } from "./connector-client.js";
5
5
  import { ConversationManager } from "./conversation-manager.js";
6
6
  import { clearEnvironmentContext } from "./environment-context.js";
7
7
  import { extractHandleFromAddress } from "./handle-utils.js";
8
8
  import { clearOwnerState, isOwnerAddress, markOwnerAddress, setCurrentTurnIsOwner, setCurrentTurnOwnerSignal, } from "./owner-session-state.js";
9
+ import { ServicesRetainedRecipientConsumer, } from "./services-retained-recipient.js";
9
10
  import { createReplyTraceMetadata, ensureTraceMetadata, } from "./trace-metadata.js";
10
- import { setCurrentTurnSender, setCurrentTurnSenderAddress, } from "./turn-context.js";
11
+ import { setCurrentTurnReplyRoute, setCurrentTurnSender, setCurrentTurnSenderAddress, } from "./turn-context.js";
11
12
  import { checkForUpdate } from "./update-check.js";
12
13
  const dbg = createDebug("agent-network:channel");
14
+ const SERVICES_RETAINED_INBOX_PEER = "agent-network:services-retained-node-inbox";
13
15
  let notificationAttempted = false;
14
16
  let identityLinkingNudgePending = false;
15
17
  let storedOwnerPassportAddress = null;
@@ -110,7 +112,7 @@ function isDuplicate(from, content, sentAt) {
110
112
  }
111
113
  return false;
112
114
  }
113
- async function handleAddressedMessage(event, conversationManager, client, ctx) {
115
+ async function handleAddressedMessage(event, conversationManager, client, ctx, options = {}) {
114
116
  const fromAddress = event.from;
115
117
  dbg("routing inbound message from=%s contentLength=%d", fromAddress, event.content.length);
116
118
  const inboundTrace = ensureTraceMetadata(event.metadata);
@@ -121,16 +123,21 @@ async function handleAddressedMessage(event, conversationManager, client, ctx) {
121
123
  console.warn(`[agent-network:channel] invalid traceparent from=${fromAddress} traceId=${inboundTrace.traceId} spanName=receive`);
122
124
  }
123
125
  }
124
- if (isDuplicate(fromAddress, event.content, event.sentAt)) {
126
+ if (!options.servicesRetained &&
127
+ isDuplicate(fromAddress, event.content, event.sentAt)) {
125
128
  dbg("duplicate message suppressed from=%s sentAt=%s", fromAddress, event.sentAt);
126
- return;
129
+ return true;
127
130
  }
128
131
  const inboundCorrelationId = typeof metadata.correlation_id === "string"
129
132
  ? metadata.correlation_id
130
133
  : undefined;
131
134
  const inboundMessageId = typeof event.messageId === "string" ? event.messageId : undefined;
132
- const nodeRef = tryProjectNodeRef(metadata);
133
- if (nodeRef) {
135
+ const nodeRef = options.servicesRetained ? null : tryProjectNodeRef(metadata);
136
+ if (options.servicesRetained) {
137
+ setCurrentTurnIsOwner(false);
138
+ setCurrentTurnOwnerSignal(null);
139
+ }
140
+ else if (nodeRef) {
134
141
  setCurrentTurnIsOwner(false);
135
142
  setCurrentTurnOwnerSignal(null);
136
143
  dbg("Full Node sender: kind=%s mstpAddress=%s handle=%s", nodeRef.kind, nodeRef.mstpAddress, nodeRef.handle ?? "(absent)");
@@ -161,35 +168,39 @@ async function handleAddressedMessage(event, conversationManager, client, ctx) {
161
168
  setCurrentTurnOwnerSignal(null);
162
169
  }
163
170
  }
164
- const contact = nodeRef
165
- ? deriveNodeName(nodeRef, fromAddress)
166
- : deriveSenderName(event);
167
- if (!conversationManager.getContactByAddress(fromAddress)) {
168
- conversationManager.registerInbound(contact, fromAddress);
171
+ const contact = options.senderName ??
172
+ (nodeRef ? deriveNodeName(nodeRef, fromAddress) : deriveSenderName(event));
173
+ const replyAddress = options.routableReplyAddress ??
174
+ (options.servicesRetained ? undefined : fromAddress);
175
+ setCurrentTurnReplyRoute(replyAddress ? "routable" : "unavailable");
176
+ if (replyAddress && !conversationManager.getContactByAddress(replyAddress)) {
177
+ conversationManager.registerInbound(contact, replyAddress);
169
178
  }
170
- setCurrentTurnSender(conversationManager.getContactByAddress(fromAddress) ?? null);
171
- setCurrentTurnSenderAddress(fromAddress);
179
+ setCurrentTurnSender(contact);
180
+ setCurrentTurnSenderAddress(replyAddress ?? null);
172
181
  let runtime;
173
182
  try {
174
183
  runtime = requirePluginRuntime();
175
184
  }
176
185
  catch {
177
186
  dbg("plugin runtime not available, dropping message from=%s", fromAddress);
178
- return;
187
+ return false;
179
188
  }
180
189
  if (!runtime.channel) {
181
190
  dbg("channelRuntime not available, dropping message from=%s", fromAddress);
182
- return;
191
+ return false;
183
192
  }
184
- const senderId = fromAddress;
193
+ const senderId = options.runtimePeerId ?? fromAddress;
185
194
  const senderName = contact;
186
- conversationManager.recordInboundEnvelope(fromAddress, {
187
- traceparent: typeof metadata.traceparent === "string"
188
- ? metadata.traceparent
189
- : undefined,
190
- correlationId: inboundCorrelationId,
191
- messageId: inboundMessageId,
192
- });
195
+ if (replyAddress) {
196
+ conversationManager.recordInboundEnvelope(replyAddress, {
197
+ traceparent: typeof metadata.traceparent === "string"
198
+ ? metadata.traceparent
199
+ : undefined,
200
+ correlationId: inboundCorrelationId,
201
+ messageId: inboundMessageId,
202
+ });
203
+ }
193
204
  try {
194
205
  const route = await runtime.channel.routing.resolveAgentRoute({
195
206
  cfg: ctx.cfg,
@@ -211,7 +222,8 @@ async function handleAddressedMessage(event, conversationManager, client, ctx) {
211
222
  Timestamp: event.sentAt ? new Date(event.sentAt).getTime() : Date.now(),
212
223
  Provider: "agent-network",
213
224
  Surface: "agent-network",
214
- MessageSid: `an:${extractHandleFromAddress(fromAddress)}:${randomUUID()}`,
225
+ MessageSid: options.messageSid ??
226
+ `an:${extractHandleFromAddress(fromAddress)}:${randomUUID()}`,
215
227
  CommandAuthorized: true,
216
228
  OriginatingChannel: "agent-network",
217
229
  OriginatingTo: senderId,
@@ -230,9 +242,11 @@ async function handleAddressedMessage(event, conversationManager, client, ctx) {
230
242
  console.error(`[agent-network:${ctx.accountId}] session record error:`, err);
231
243
  },
232
244
  });
233
- client.sendTyping(fromAddress, true);
245
+ if (replyAddress)
246
+ client.sendTyping(replyAddress, true);
234
247
  let replyDelivered = false;
235
248
  let suppressedBlocks = 0;
249
+ let dispatchError;
236
250
  try {
237
251
  await runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
238
252
  ctx: msgCtx,
@@ -242,6 +256,10 @@ async function handleAddressedMessage(event, conversationManager, client, ctx) {
242
256
  const text = payload.text;
243
257
  if (!text)
244
258
  return;
259
+ if (!replyAddress) {
260
+ suppressedBlocks++;
261
+ return;
262
+ }
245
263
  if (!conversationManager.hasConversation(senderId)) {
246
264
  suppressedBlocks++;
247
265
  return;
@@ -250,7 +268,7 @@ async function handleAddressedMessage(event, conversationManager, client, ctx) {
250
268
  correlationId: inboundCorrelationId,
251
269
  messageId: inboundMessageId,
252
270
  });
253
- const deliverResult = await conversationManager.send(senderId, text, replyTrace.metadata);
271
+ const deliverResult = await conversationManager.send(replyAddress, text, replyTrace.metadata);
254
272
  if (deliverResult.status === "sent") {
255
273
  replyDelivered = true;
256
274
  }
@@ -260,26 +278,49 @@ async function handleAddressedMessage(event, conversationManager, client, ctx) {
260
278
  dbg("deliver reply senderId=%s status=%s contentLength=%d traceId=%s originalTraceId=%s spanName=send", senderId, deliverResult.status, text.length, replyTrace.traceId, replyTrace.originalTraceId ?? "(absent)");
261
279
  },
262
280
  onError: (err) => {
281
+ dispatchError = err;
263
282
  console.error(`[agent-network:${ctx.accountId}] dispatch error:`, err);
264
283
  },
265
284
  },
266
285
  });
286
+ if (dispatchError)
287
+ throw dispatchError;
267
288
  if (suppressedBlocks > 0) {
268
- console.warn(`[agent-network:${ctx.accountId}] reply suppressed (conversation ended) from=${senderId} blocks=${suppressedBlocks}`);
289
+ console.warn(options.servicesRetained
290
+ ? `[agent-network:${ctx.accountId}] reply not routed for Services-retained message: canonical envelope has no reply address blocks=${suppressedBlocks}`
291
+ : `[agent-network:${ctx.accountId}] reply suppressed (conversation ended) from=${senderId} blocks=${suppressedBlocks}`);
269
292
  }
270
293
  else if (!replyDelivered) {
271
294
  console.log(`[agent-network:${ctx.accountId}] dispatch completed without in-turn reply text from=${senderId} (tool-path reply or silence)`);
272
295
  }
273
296
  }
274
297
  finally {
275
- client.sendTyping(fromAddress, false);
298
+ if (replyAddress)
299
+ client.sendTyping(replyAddress, false);
276
300
  conversationManager.commitEndedConversations();
277
301
  }
302
+ return true;
278
303
  }
279
304
  catch (err) {
280
305
  console.error(`[agent-network:${ctx.accountId}] inbound dispatch failed from=${fromAddress}:`, err);
306
+ return false;
281
307
  }
282
308
  }
309
+ function servicesRetainedSenderName(message) {
310
+ const { display_name: displayName, handle } = message.envelope.sender;
311
+ if (displayName && handle)
312
+ return `${displayName} (handle: ${handle})`;
313
+ return displayName ?? handle ?? "MASONS sender unavailable";
314
+ }
315
+ function servicesRetainedBody(message) {
316
+ const sender = servicesRetainedSenderName(message);
317
+ const displayName = message.envelope.sender.display_name;
318
+ const handle = message.envelope.sender.handle;
319
+ return [
320
+ `[MASONS canonical message_ref=${JSON.stringify(message.envelope.message_ref)}; sender_display_name=${displayName === undefined ? "absent" : JSON.stringify(displayName)}; sender_handle=${handle === undefined ? "absent" : JSON.stringify(handle)}; sender_label=${JSON.stringify(sender)}; content_type=${JSON.stringify(message.contentType)}]`,
321
+ message.envelope.content,
322
+ ].join("\n\n");
323
+ }
283
324
  const accounts = new Map();
284
325
  export const agentNetworkChannel = {
285
326
  id: "agent-network",
@@ -354,9 +395,35 @@ export const agentNetworkChannel = {
354
395
  const { connectorUrl, token } = ctx.account;
355
396
  const client = new ConnectorClient(connectorUrl, token);
356
397
  const conversationManager = new ConversationManager(client);
398
+ const servicesRetainedRecipient = new ServicesRetainedRecipientConsumer({
399
+ apiHost: requirePlatformConfig().apiHost,
400
+ runtimeKey: token,
401
+ logger: {
402
+ info: (message) => console.log(`[agent-network:${ctx.accountId}] ${message}`),
403
+ warn: (message) => console.warn(`[agent-network:${ctx.accountId}] ${message}`),
404
+ error: (message, error) => console.error(`[agent-network:${ctx.accountId}] ${message}`, error ?? ""),
405
+ },
406
+ present: async (message) => handleAddressedMessage({
407
+ event: "MESSAGE_RECEIVED",
408
+ messageId: message.envelope.message_ref,
409
+ from: SERVICES_RETAINED_INBOX_PEER,
410
+ content: servicesRetainedBody(message),
411
+ contentType: message.contentType,
412
+ metadata: {},
413
+ ...(message.envelope.sent_at && {
414
+ sentAt: message.envelope.sent_at,
415
+ }),
416
+ }, conversationManager, client, ctx, {
417
+ runtimePeerId: SERVICES_RETAINED_INBOX_PEER,
418
+ senderName: servicesRetainedSenderName(message),
419
+ messageSid: `an:${message.envelope.message_ref}`,
420
+ servicesRetained: true,
421
+ }),
422
+ });
357
423
  const state = {
358
424
  client,
359
425
  conversationManager,
426
+ servicesRetainedRecipient,
360
427
  };
361
428
  accounts.set(ctx.accountId, state);
362
429
  client.on("message_received", async (event) => {
@@ -364,6 +431,12 @@ export const agentNetworkChannel = {
364
431
  return;
365
432
  await handleAddressedMessage(event, conversationManager, client, ctx);
366
433
  });
434
+ client.on("custody_pending", () => {
435
+ void servicesRetainedRecipient.requestDrain();
436
+ });
437
+ client.on("connected", () => {
438
+ void servicesRetainedRecipient.requestDrain();
439
+ });
367
440
  client.on("delivery_pending", (event) => {
368
441
  dbg("legacy delivery_pending ignored count=%d upTo=%s", event.count, event.upTo);
369
442
  });
@@ -375,6 +448,7 @@ export const agentNetworkChannel = {
375
448
  console.error(`[agent-network:${ctx.accountId}]`, err.message);
376
449
  });
377
450
  ctx.abortSignal.addEventListener("abort", () => {
451
+ void servicesRetainedRecipient.stop();
378
452
  client.disconnect();
379
453
  }, { once: true });
380
454
  const networkCfg = extractNetworkConfig(ctx.cfg);
@@ -384,6 +458,7 @@ export const agentNetworkChannel = {
384
458
  dbg("connected account=%s", ctx.accountId);
385
459
  initConnectorClient(client);
386
460
  initConversationManager(conversationManager);
461
+ void servicesRetainedRecipient.start();
387
462
  await new Promise((resolve) => {
388
463
  if (ctx.abortSignal.aborted) {
389
464
  resolve();
@@ -398,6 +473,7 @@ export const agentNetworkChannel = {
398
473
  dbg("stopping account %s", ctx.accountId);
399
474
  const state = accounts.get(ctx.accountId);
400
475
  if (state) {
476
+ await state.servicesRetainedRecipient.stop();
401
477
  clearConversationManager();
402
478
  clearConnectorClient();
403
479
  state.client.removeAllListeners();
@@ -1 +1 @@
1
- {"version":3,"file":"cli-setup.d.ts","sourceRoot":"","sources":["../src/cli-setup.ts"],"names":[],"mappings":"AAyFA,UAAU,eAAe;IACvB,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC9B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAOD,UAAU,gBAAgB;IACxB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAiFD,wBAAsB,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmEhE"}
1
+ {"version":3,"file":"cli-setup.d.ts","sourceRoot":"","sources":["../src/cli-setup.ts"],"names":[],"mappings":"AAyFA,UAAU,eAAe;IACvB,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC9B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAOD,UAAU,gBAAgB;IACxB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAgFD,wBAAsB,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmEhE"}
package/dist/cli-setup.js CHANGED
@@ -7,7 +7,6 @@ async function serverBridgeHandoffFlow(apiHost, idpBaseUrl, runtime, channelInpu
7
7
  apiHost,
8
8
  idpBaseUrl,
9
9
  channelInput,
10
- sessionTopology: "single_session",
11
10
  });
12
11
  runtime.writeStdout([
13
12
  "",
@@ -1,5 +1,5 @@
1
1
  import { EventEmitter } from "node:events";
2
- import { type AddressedMessageEvent, type DeliveryPendingEvent, type DeliveryStatusEvent, type SendAckEvent, type StructuredErrorEvent } from "./types.js";
2
+ import { type AddressedMessageEvent, type CustodyPendingEvent, type DeliveryPendingEvent, type DeliveryStatusEvent, type SendAckEvent, type StructuredErrorEvent } from "./types.js";
3
3
  export declare class ConnectorError extends Error {
4
4
  readonly code: string;
5
5
  readonly to?: string;
@@ -7,6 +7,7 @@ export declare class ConnectorError extends Error {
7
7
  }
8
8
  type ConnectorClientEvents = {
9
9
  message_received: (event: AddressedMessageEvent) => void;
10
+ custody_pending: (event: CustodyPendingEvent) => void;
10
11
  send_ack: (event: SendAckEvent) => void;
11
12
  delivery_pending: (event: DeliveryPendingEvent) => void;
12
13
  delivery_status: (event: DeliveryStatusEvent) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"connector-client.d.ts","sourceRoot":"","sources":["../src/connector-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connector-client.d.ts","sourceRoot":"","sources":["../src/connector-client.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import { EventEmitter } from "node:events";
3
3
  import createDebug from "debug";
4
4
  import WebSocket from "ws";
5
5
  import { setEnvironmentContext } from "./environment-context.js";
6
- import { CURRENT_PROTOCOL_VERSION, isAddressedMessage, isDeliveryCursor, isDeliveryPending, isDeliverySkip, isDeliveryStatus, isRegisterAck, isSendAck, isStructuredError, REGISTER_ACK_TIMEOUT_MS, SEND_ACK_TIMEOUT_MS, } from "./types.js";
6
+ import { CURRENT_PROTOCOL_VERSION, isAddressedMessage, isCustodyPending, isDeliveryCursor, isDeliveryPending, isDeliverySkip, isDeliveryStatus, isRegisterAck, isSendAck, isStructuredError, REGISTER_ACK_TIMEOUT_MS, SEND_ACK_TIMEOUT_MS, } from "./types.js";
7
7
  import { PLUGIN_VERSION } from "./version.js";
8
8
  const dbg = createDebug("agent-network:connector");
9
9
  const dbgMsg = createDebug("agent-network:connector:msg");
@@ -201,6 +201,11 @@ export class ConnectorClient extends EventEmitter {
201
201
  this.handleAddressedMessage(parsed);
202
202
  return;
203
203
  }
204
+ if (isCustodyPending(parsed)) {
205
+ dbg("CUSTODY_PENDING");
206
+ this.emit("custody_pending", parsed);
207
+ return;
208
+ }
204
209
  if (isDeliveryPending(parsed)) {
205
210
  dbg("DELIVERY_PENDING count=%d upTo=%s", parsed.count, parsed.upTo);
206
211
  this.emit("delivery_pending", parsed);
package/dist/handoff.d.ts CHANGED
@@ -3,7 +3,6 @@ export declare const DEFAULT_IDP_BASE_URL = "https://preview.masons.ai";
3
3
  export declare const HANDOFF_TIMEOUT_MS: number;
4
4
  export declare class SetupFlowError extends Error {
5
5
  }
6
- export type AgentSessionTopology = "single_session" | "multi_session";
7
6
  export interface BridgeHandoffResult {
8
7
  token: string;
9
8
  agent: {
@@ -23,7 +22,6 @@ export interface BeginBridgeHandoffOptions {
23
22
  apiHost: string;
24
23
  idpBaseUrl: string;
25
24
  channelInput?: string;
26
- sessionTopology?: AgentSessionTopology;
27
25
  }
28
26
  export declare function beginBridgeHandoff(options: BeginBridgeHandoffOptions): Promise<BridgeHandoffSession>;
29
27
  export declare function completeBridgeHandoff(session: BridgeHandoffSession): Promise<BridgeHandoffResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"handoff.d.ts","sourceRoot":"","sources":["../src/handoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EAEf,MAAM,aAAa,CAAC;AAerB,eAAO,MAAM,oBAAoB,8BAA8B,CAAC;AAiBhE,eAAO,MAAM,kBAAkB,QAAgB,CAAC;AAKhD,qBAAa,cAAe,SAAQ,KAAK;CAAG;AAY5C,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG,eAAe,CAAC;AAEtE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1D;AAQD,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAOhB,UAAU,EAAE,SAAS,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,oBAAoB,CAAC;CACxC;AAMD,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,oBAAoB,CAAC,CAyD/B;AAKD,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAmC9B"}
1
+ {"version":3,"file":"handoff.d.ts","sourceRoot":"","sources":["../src/handoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EAEf,MAAM,aAAa,CAAC;AAerB,eAAO,MAAM,oBAAoB,8BAA8B,CAAC;AAiBhE,eAAO,MAAM,kBAAkB,QAAgB,CAAC;AAKhD,qBAAa,cAAe,SAAQ,KAAK;CAAG;AAY5C,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1D;AAQD,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAOhB,UAAU,EAAE,SAAS,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,oBAAoB,CAAC,CAsD/B;AAKD,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAmC9B"}
package/dist/handoff.js CHANGED
@@ -21,9 +21,6 @@ export async function beginBridgeHandoff(options) {
21
21
  headers: { "content-type": "application/json" },
22
22
  body: JSON.stringify({
23
23
  cli_pubkey: cliPubkeySpki,
24
- ...(options.sessionTopology !== undefined
25
- ? { session_topology: options.sessionTopology }
26
- : {}),
27
24
  }),
28
25
  });
29
26
  if (!initRes.ok) {
package/dist/plugin.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare function buildInteractionContext(channelId: string | undefined, turnSender: string | null, turnSenderAddress: string | null): string | undefined;
1
+ export declare function buildInteractionContext(channelId: string | undefined, turnSender: string | null, turnSenderAddress: string | null, turnReplyRoute?: "routable" | "unavailable" | null): string | undefined;
2
2
  interface OpenClawPluginApi {
3
3
  runtime: unknown;
4
4
  registerChannel(opts: {
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAqFA,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAC/B,MAAM,GAAG,SAAS,CA6EpB;AAKD,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,YAAY,CACV,IAAI,EAAE,OAAO,EACb,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3C,IAAI,CAAC;IACR,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;CACnE;AAED,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAaI,iBAAiB;CAqYhC,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAsFA,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,EAChC,cAAc,GAAE,UAAU,GAAG,aAAa,GAAG,IAAW,GACvD,MAAM,GAAG,SAAS,CA+EpB;AAKD,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,YAAY,CACV,IAAI,EAAE,OAAO,EACb,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3C,IAAI,CAAC;IACR,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;CACnE;AAED,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAaI,iBAAiB;CA2YhC,CAAC;AAEF,eAAe,MAAM,CAAC"}
package/dist/plugin.js CHANGED
@@ -7,7 +7,7 @@ import { ownerNotesQueue } from "./owner-notes.js";
7
7
  import { consumeCurrentTurnIsOwner, consumeCurrentTurnOwnerSignal, } from "./owner-session-state.js";
8
8
  import { sentMessageBuffer } from "./sent-message-buffer.js";
9
9
  import { registerTools } from "./tools.js";
10
- import { consumeCurrentTurnSender, consumeCurrentTurnSenderAddress, setCurrentTurnChannelId, setCurrentTurnIsOwnerForTools, setCurrentTurnOwnerSignalForTools, } from "./turn-context.js";
10
+ import { consumeCurrentTurnReplyRoute, consumeCurrentTurnSender, consumeCurrentTurnSenderAddress, setCurrentTurnChannelId, setCurrentTurnIsOwnerForTools, setCurrentTurnOwnerSignalForTools, } from "./turn-context.js";
11
11
  import { getUpdateInfo } from "./update-check.js";
12
12
  import { PLUGIN_VERSION } from "./version.js";
13
13
  function formatTimeAgo(timestamp) {
@@ -38,7 +38,7 @@ function drainAndFormatNotes(reportInstruction) {
38
38
  reportInstruction);
39
39
  }
40
40
  const MAX_INTERACTIONS = 5;
41
- export function buildInteractionContext(channelId, turnSender, turnSenderAddress) {
41
+ export function buildInteractionContext(channelId, turnSender, turnSenderAddress, turnReplyRoute = null) {
42
42
  const cm = getConversationManager();
43
43
  if (!cm)
44
44
  return undefined;
@@ -71,7 +71,9 @@ export function buildInteractionContext(channelId, turnSender, turnSenderAddress
71
71
  : turnSender;
72
72
  return (`${header}\n${lines.join("\n")}\n` +
73
73
  `[This turn] From ${from}. ${initiated}\n` +
74
- "Your text reply goes to this sender. " +
74
+ (turnReplyRoute === "unavailable"
75
+ ? "No reply route is available for this message. "
76
+ : "Your text reply goes to this sender. ") +
75
77
  "To report to your owner: masons_note_for_owner.");
76
78
  }
77
79
  if (isNetworkTurn) {
@@ -143,6 +145,7 @@ const plugin = {
143
145
  const turnOwnerSignal = consumeCurrentTurnOwnerSignal();
144
146
  const turnSender = consumeCurrentTurnSender();
145
147
  const turnSenderAddress = consumeCurrentTurnSenderAddress();
148
+ const turnReplyRoute = consumeCurrentTurnReplyRoute();
146
149
  setCurrentTurnChannelId(channelId ?? null);
147
150
  setCurrentTurnIsOwnerForTools(turnIsOwner);
148
151
  setCurrentTurnOwnerSignalForTools(turnOwnerSignal);
@@ -209,11 +212,15 @@ const plugin = {
209
212
  }
210
213
  else {
211
214
  dynamicContext =
212
- "[Agent Network — Routing] This turn was triggered by a message " +
213
- "on the agent network. Your text reply will be sent to that sender — " +
214
- "your owner (Principal) will NOT see it. To report something to your owner, " +
215
- "call masons_note_for_owner.";
216
- const interactionCtx = buildInteractionContext(channelId, turnSender, turnSenderAddress);
215
+ turnReplyRoute === "unavailable"
216
+ ? "[Agent Network Services-retained message] This canonical message carries no reply address. " +
217
+ "A plain text reply will NOT be routed to its sender. Do not infer or fabricate an address or Session. " +
218
+ "Treat the message as inbound information; to report something to your owner, call masons_note_for_owner."
219
+ : "[Agent Network Routing] This turn was triggered by a message " +
220
+ "on the agent network. Your text reply will be sent to that sender — " +
221
+ "your owner (Principal) will NOT see it. To report something to your owner, " +
222
+ "call masons_note_for_owner.";
223
+ const interactionCtx = buildInteractionContext(channelId, turnSender, turnSenderAddress, turnReplyRoute);
217
224
  if (interactionCtx) {
218
225
  dynamicContext += `\n\n${interactionCtx}`;
219
226
  }
@@ -0,0 +1,58 @@
1
+ import { type RuntimeExactTargetPresentationEnvelopeV1 } from "./_vendor/runtime-adapter-client/index.js";
2
+ export interface ServicesRetainedRecipientPresentation {
3
+ contentType: string;
4
+ envelope: RuntimeExactTargetPresentationEnvelopeV1;
5
+ }
6
+ export interface ServicesRetainedRecipientLogger {
7
+ info(message: string): void;
8
+ warn(message: string): void;
9
+ error(message: string, error?: unknown): void;
10
+ }
11
+ export interface ServicesRetainedRecipientOptions {
12
+ apiHost: string;
13
+ runtimeKey: string;
14
+ present: (message: ServicesRetainedRecipientPresentation) => Promise<boolean>;
15
+ logger: ServicesRetainedRecipientLogger;
16
+ endpointNonce?: string;
17
+ retryDelayMs?: number;
18
+ minimumHeartbeatDelayMs?: number;
19
+ fetch?: typeof fetch;
20
+ }
21
+ export declare class ServicesRetainedRecipientConsumer {
22
+ private readonly clientConfig;
23
+ private readonly runtimeKey;
24
+ private readonly present;
25
+ private readonly logger;
26
+ private readonly endpointNonce;
27
+ private readonly retryDelayMs;
28
+ private readonly minimumHeartbeatDelayMs;
29
+ private endpoint;
30
+ private presentedOffer;
31
+ private acquirePermanentlyBlocked;
32
+ private consumptionPermanentlyBlocked;
33
+ private consecutiveHeartbeatNotFound;
34
+ private stopped;
35
+ private activationPromise;
36
+ private drainPromise;
37
+ private drainRequested;
38
+ private activationRetryTimer;
39
+ private drainRetryTimer;
40
+ private heartbeatTimer;
41
+ private stopPromise;
42
+ constructor(options: ServicesRetainedRecipientOptions);
43
+ start(): Promise<void>;
44
+ stop(): Promise<void>;
45
+ requestDrain(): Promise<void>;
46
+ private activate;
47
+ private drain;
48
+ private consumePresentedOffer;
49
+ private scheduleHeartbeat;
50
+ private heartbeat;
51
+ private recoverEndpoint;
52
+ private scheduleActivationRetry;
53
+ private scheduleDrainRetry;
54
+ private clearActivationRetryTimer;
55
+ private clearDrainRetryTimer;
56
+ private clearHeartbeatTimer;
57
+ }
58
+ //# sourceMappingURL=services-retained-recipient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"services-retained-recipient.d.ts","sourceRoot":"","sources":["../src/services-retained-recipient.ts"],"names":[],"mappings":"AACA,OAAO,EAML,KAAK,wCAAwC,EAI9C,MAAM,2CAA2C,CAAC;AAKnD,MAAM,WAAW,qCAAqC;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,wCAAwC,CAAC;CACpD;AAED,MAAM,WAAW,+BAA+B;IAC9C,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,gCAAgC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,CAAC,OAAO,EAAE,qCAAqC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9E,MAAM,EAAE,+BAA+B,CAAC;IACxC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAaD,qBAAa,iCAAiC;IAC5C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6B;IAC1D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8C;IACtE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IACzD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAS;IAEjD,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,yBAAyB,CAAS;IAC1C,OAAO,CAAC,6BAA6B,CAAS;IAC9C,OAAO,CAAC,4BAA4B,CAAK;IACzC,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,iBAAiB,CAA8B;IACvD,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,oBAAoB,CAA8C;IAC1E,OAAO,CAAC,eAAe,CAA8C;IACrE,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,WAAW,CAA8B;gBAErC,OAAO,EAAE,gCAAgC;IAc/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAiCrB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;YAerB,QAAQ;YAoDR,KAAK;YA0EL,qBAAqB;IAwDnC,OAAO,CAAC,iBAAiB;YAcX,SAAS;IAgCvB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,uBAAuB;IAS/B,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,yBAAyB;IAKjC,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,mBAAmB;CAI5B"}