@masons/agent-network 0.6.17 → 0.6.18

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 CHANGED
@@ -3,7 +3,7 @@ import type { AgentNetworkAccount } from "./config-schema.js";
3
3
  export declare function getOwnerPassportAddress(): string | null;
4
4
  export declare function consumeIdentityLinkingNudge(): boolean;
5
5
  export declare function _setNudgePendingForTesting(value: boolean): void;
6
- declare function withAgentNetworkSilentReplyPolicy(cfg: Record<string, unknown>): Record<string, unknown>;
6
+ declare function withAgentNetworkSilentReplyPolicy(cfg: Record<string, unknown>, servicesRetained?: boolean): Record<string, unknown>;
7
7
  export declare const _withAgentNetworkSilentReplyPolicyForTesting: typeof withAgentNetworkSilentReplyPolicy;
8
8
  export declare const agentNetworkChannel: ChannelPlugin<AgentNetworkAccount>;
9
9
  export {};
@@ -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;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"}
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;AAsD9D,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,EAC5B,gBAAgB,UAAQ,GACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuCzB;AAED,eAAO,MAAM,4CAA4C,0CACtB,CAAC;AAyiBpC,eAAO,MAAM,mBAAmB,EAAE,aAAa,CAAC,mBAAmB,CAoRlE,CAAC"}
package/dist/channel.js CHANGED
@@ -7,8 +7,9 @@ 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
9
  import { ServicesRetainedRecipientConsumer, } from "./services-retained-recipient.js";
10
+ import { isServicesRetainedReplyContext, runWithServicesRetainedReplyContext, } from "./services-retained-reply-context.js";
10
11
  import { createReplyTraceMetadata, ensureTraceMetadata, } from "./trace-metadata.js";
11
- import { setCurrentTurnReplyRoute, setCurrentTurnSender, setCurrentTurnSenderAddress, } from "./turn-context.js";
12
+ import { setCurrentTurnSender, setCurrentTurnSenderAddress, } from "./turn-context.js";
12
13
  import { checkForUpdate } from "./update-check.js";
13
14
  const dbg = createDebug("agent-network:channel");
14
15
  const SERVICES_RETAINED_INBOX_PEER = "agent-network:services-retained-node-inbox";
@@ -30,7 +31,7 @@ export function _setNudgePendingForTesting(value) {
30
31
  function isRecord(value) {
31
32
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
32
33
  }
33
- function withAgentNetworkSilentReplyPolicy(cfg) {
34
+ function withAgentNetworkSilentReplyPolicy(cfg, servicesRetained = false) {
34
35
  const surfaces = isRecord(cfg.surfaces) ? cfg.surfaces : {};
35
36
  const existingSurface = isRecord(surfaces["agent-network"])
36
37
  ? surfaces["agent-network"]
@@ -41,6 +42,10 @@ function withAgentNetworkSilentReplyPolicy(cfg) {
41
42
  const silentReplyRewrite = isRecord(existingSurface.silentReplyRewrite)
42
43
  ? existingSurface.silentReplyRewrite
43
44
  : {};
45
+ const tools = isRecord(cfg.tools) ? cfg.tools : {};
46
+ const deny = Array.isArray(tools.deny)
47
+ ? tools.deny.filter((value) => typeof value === "string")
48
+ : [];
44
49
  return {
45
50
  ...cfg,
46
51
  surfaces: {
@@ -57,6 +62,12 @@ function withAgentNetworkSilentReplyPolicy(cfg) {
57
62
  },
58
63
  },
59
64
  },
65
+ ...(servicesRetained && {
66
+ tools: {
67
+ ...tools,
68
+ deny: [...new Set([...deny, "message"])],
69
+ },
70
+ }),
60
71
  };
61
72
  }
62
73
  export const _withAgentNetworkSilentReplyPolicyForTesting = withAgentNetworkSilentReplyPolicy;
@@ -123,7 +134,7 @@ async function handleAddressedMessage(event, conversationManager, client, ctx, o
123
134
  console.warn(`[agent-network:channel] invalid traceparent from=${fromAddress} traceId=${inboundTrace.traceId} spanName=receive`);
124
135
  }
125
136
  }
126
- if (!options.servicesRetained &&
137
+ if (options.servicesRetained === undefined &&
127
138
  isDuplicate(fromAddress, event.content, event.sentAt)) {
128
139
  dbg("duplicate message suppressed from=%s sentAt=%s", fromAddress, event.sentAt);
129
140
  return true;
@@ -172,7 +183,6 @@ async function handleAddressedMessage(event, conversationManager, client, ctx, o
172
183
  (nodeRef ? deriveNodeName(nodeRef, fromAddress) : deriveSenderName(event));
173
184
  const replyAddress = options.routableReplyAddress ??
174
185
  (options.servicesRetained ? undefined : fromAddress);
175
- setCurrentTurnReplyRoute(replyAddress ? "routable" : "unavailable");
176
186
  if (replyAddress && !conversationManager.getContactByAddress(replyAddress)) {
177
187
  conversationManager.registerInbound(contact, replyAddress);
178
188
  }
@@ -244,18 +254,23 @@ async function handleAddressedMessage(event, conversationManager, client, ctx, o
244
254
  });
245
255
  if (replyAddress)
246
256
  client.sendTyping(replyAddress, true);
247
- let replyDelivered = false;
257
+ let replyRouted = false;
258
+ const servicesRetainedReplyBlocks = [];
248
259
  let suppressedBlocks = 0;
249
260
  let dispatchError;
250
261
  try {
251
- await runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
262
+ const dispatch = () => runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
252
263
  ctx: msgCtx,
253
- cfg: withAgentNetworkSilentReplyPolicy(ctx.cfg),
264
+ cfg: withAgentNetworkSilentReplyPolicy(ctx.cfg, options.servicesRetained !== undefined),
254
265
  dispatcherOptions: {
255
266
  deliver: async (payload) => {
256
267
  const text = payload.text;
257
268
  if (!text)
258
269
  return;
270
+ if (options.servicesRetained) {
271
+ servicesRetainedReplyBlocks.push(text);
272
+ return;
273
+ }
259
274
  if (!replyAddress) {
260
275
  suppressedBlocks++;
261
276
  return;
@@ -270,7 +285,7 @@ async function handleAddressedMessage(event, conversationManager, client, ctx, o
270
285
  });
271
286
  const deliverResult = await conversationManager.send(replyAddress, text, replyTrace.metadata);
272
287
  if (deliverResult.status === "sent") {
273
- replyDelivered = true;
288
+ replyRouted = true;
274
289
  }
275
290
  else {
276
291
  console.warn(`[agent-network:${ctx.accountId}] reply send FAILED to=${senderId} code=${deliverResult.errorCode ?? "(none)"} error=${deliverResult.error ?? "(none)"}`);
@@ -283,14 +298,29 @@ async function handleAddressedMessage(event, conversationManager, client, ctx, o
283
298
  },
284
299
  },
285
300
  });
301
+ if (options.servicesRetained) {
302
+ await runWithServicesRetainedReplyContext(dispatch);
303
+ }
304
+ else {
305
+ await dispatch();
306
+ }
286
307
  if (dispatchError)
287
308
  throw dispatchError;
309
+ if (options.servicesRetained && servicesRetainedReplyBlocks.length > 0) {
310
+ const replyResult = await options.servicesRetained.reply(servicesRetainedReplyBlocks.join("\n\n"));
311
+ if (replyResult.status === "staged") {
312
+ replyRouted = true;
313
+ }
314
+ else {
315
+ throw new Error(`${replyResult.errorCode}: ${replyResult.error}`);
316
+ }
317
+ }
288
318
  if (suppressedBlocks > 0) {
289
319
  console.warn(options.servicesRetained
290
320
  ? `[agent-network:${ctx.accountId}] reply not routed for Services-retained message: canonical envelope has no reply address blocks=${suppressedBlocks}`
291
321
  : `[agent-network:${ctx.accountId}] reply suppressed (conversation ended) from=${senderId} blocks=${suppressedBlocks}`);
292
322
  }
293
- else if (!replyDelivered) {
323
+ else if (!replyRouted) {
294
324
  console.log(`[agent-network:${ctx.accountId}] dispatch completed without in-turn reply text from=${senderId} (tool-path reply or silence)`);
295
325
  }
296
326
  }
@@ -372,6 +402,9 @@ export const agentNetworkChannel = {
372
402
  outbound: {
373
403
  deliveryMode: "direct",
374
404
  async sendText(ctx) {
405
+ if (isServicesRetainedReplyContext()) {
406
+ throw new Error("services_retained_generic_send_forbidden");
407
+ }
375
408
  const state = ctx.accountId ? accounts.get(ctx.accountId) : undefined;
376
409
  if (!state)
377
410
  return { channel: "agent-network", messageId: "" };
@@ -417,7 +450,7 @@ export const agentNetworkChannel = {
417
450
  runtimePeerId: SERVICES_RETAINED_INBOX_PEER,
418
451
  senderName: servicesRetainedSenderName(message),
419
452
  messageSid: `an:${message.envelope.message_ref}`,
420
- servicesRetained: true,
453
+ servicesRetained: { reply: message.reply },
421
454
  }),
422
455
  });
423
456
  const state = {
package/dist/plugin.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare function buildInteractionContext(channelId: string | undefined, turnSender: string | null, turnSenderAddress: string | null, turnReplyRoute?: "routable" | "unavailable" | null): string | undefined;
1
+ export declare function buildInteractionContext(channelId: string | undefined, turnSender: string | null, turnSenderAddress: string | null, servicesRetained?: boolean): 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":"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"}
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,gBAAgB,UAAQ,GACvB,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;CA0YhC,CAAC;AAEF,eAAe,MAAM,CAAC"}
package/dist/plugin.js CHANGED
@@ -6,8 +6,9 @@ import { getAgentIdentity } from "./environment-context.js";
6
6
  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
+ import { isServicesRetainedReplyContext } from "./services-retained-reply-context.js";
9
10
  import { registerTools } from "./tools.js";
10
- import { consumeCurrentTurnReplyRoute, consumeCurrentTurnSender, consumeCurrentTurnSenderAddress, setCurrentTurnChannelId, setCurrentTurnIsOwnerForTools, setCurrentTurnOwnerSignalForTools, } from "./turn-context.js";
11
+ import { consumeCurrentTurnSender, consumeCurrentTurnSenderAddress, setCurrentTurnChannelId, setCurrentTurnIsOwnerForTools, setCurrentTurnOwnerSignalForTools, } from "./turn-context.js";
11
12
  import { getUpdateInfo } from "./update-check.js";
12
13
  import { PLUGIN_VERSION } from "./version.js";
13
14
  function formatTimeAgo(timestamp) {
@@ -38,7 +39,7 @@ function drainAndFormatNotes(reportInstruction) {
38
39
  reportInstruction);
39
40
  }
40
41
  const MAX_INTERACTIONS = 5;
41
- export function buildInteractionContext(channelId, turnSender, turnSenderAddress, turnReplyRoute = null) {
42
+ export function buildInteractionContext(channelId, turnSender, turnSenderAddress, servicesRetained = false) {
42
43
  const cm = getConversationManager();
43
44
  if (!cm)
44
45
  return undefined;
@@ -71,8 +72,8 @@ export function buildInteractionContext(channelId, turnSender, turnSenderAddress
71
72
  : turnSender;
72
73
  return (`${header}\n${lines.join("\n")}\n` +
73
74
  `[This turn] From ${from}. ${initiated}\n` +
74
- (turnReplyRoute === "unavailable"
75
- ? "No reply route is available for this message. "
75
+ (servicesRetained
76
+ ? "Your text reply uses the Services-retained reply authority for this message. "
76
77
  : "Your text reply goes to this sender. ") +
77
78
  "To report to your owner: masons_note_for_owner.");
78
79
  }
@@ -145,7 +146,7 @@ const plugin = {
145
146
  const turnOwnerSignal = consumeCurrentTurnOwnerSignal();
146
147
  const turnSender = consumeCurrentTurnSender();
147
148
  const turnSenderAddress = consumeCurrentTurnSenderAddress();
148
- const turnReplyRoute = consumeCurrentTurnReplyRoute();
149
+ const servicesRetainedReply = isServicesRetainedReplyContext();
149
150
  setCurrentTurnChannelId(channelId ?? null);
150
151
  setCurrentTurnIsOwnerForTools(turnIsOwner);
151
152
  setCurrentTurnOwnerSignalForTools(turnOwnerSignal);
@@ -211,16 +212,15 @@ const plugin = {
211
212
  }
212
213
  }
213
214
  else {
214
- dynamicContext =
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);
215
+ dynamicContext = servicesRetainedReply
216
+ ? "[Agent Network — Services-retained message] Reply normally with plain text. " +
217
+ "The Host will use this message's Services-owned opaque reply authority; do not call masons_send_message, infer an address, or fabricate a Session for this reply. " +
218
+ "To report something separately 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, servicesRetainedReply);
224
224
  if (interactionCtx) {
225
225
  dynamicContext += `\n\n${interactionCtx}`;
226
226
  }
@@ -2,7 +2,17 @@ import { type RuntimeExactTargetPresentationEnvelopeV1 } from "./_vendor/runtime
2
2
  export interface ServicesRetainedRecipientPresentation {
3
3
  contentType: string;
4
4
  envelope: RuntimeExactTargetPresentationEnvelopeV1;
5
+ reply: ServicesRetainedRecipientReply;
5
6
  }
7
+ export type ServicesRetainedRecipientReplyResult = {
8
+ status: "staged";
9
+ } | {
10
+ status: "failed";
11
+ errorCode: string;
12
+ error: string;
13
+ retryable: boolean;
14
+ };
15
+ export type ServicesRetainedRecipientReply = (content: string) => Promise<ServicesRetainedRecipientReplyResult>;
6
16
  export interface ServicesRetainedRecipientLogger {
7
17
  info(message: string): void;
8
18
  warn(message: string): void;
@@ -30,6 +40,7 @@ export declare class ServicesRetainedRecipientConsumer {
30
40
  private presentedOffer;
31
41
  private acquirePermanentlyBlocked;
32
42
  private consumptionPermanentlyBlocked;
43
+ private replyPermanentlyBlocked;
33
44
  private consecutiveHeartbeatNotFound;
34
45
  private stopped;
35
46
  private activationPromise;
@@ -45,7 +56,11 @@ export declare class ServicesRetainedRecipientConsumer {
45
56
  requestDrain(): Promise<void>;
46
57
  private activate;
47
58
  private drain;
59
+ private advancePresentedOffer;
48
60
  private consumePresentedOffer;
61
+ private createReplyAction;
62
+ private submitReplyAttempt;
63
+ private submitReply;
49
64
  private scheduleHeartbeat;
50
65
  private heartbeat;
51
66
  private recoverEndpoint;
@@ -1 +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"}
1
+ {"version":3,"file":"services-retained-recipient.d.ts","sourceRoot":"","sources":["../src/services-retained-recipient.ts"],"names":[],"mappings":"AACA,OAAO,EAML,KAAK,wCAAwC,EAM9C,MAAM,2CAA2C,CAAC;AAKnD,MAAM,WAAW,qCAAqC;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,wCAAwC,CAAC;IACnD,KAAK,EAAE,8BAA8B,CAAC;CACvC;AAED,MAAM,MAAM,oCAAoC,GAC5C;IACE,MAAM,EAAE,QAAQ,CAAC;CAClB,GACD;IACE,MAAM,EAAE,QAAQ,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEN,MAAM,MAAM,8BAA8B,GAAG,CAC3C,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,oCAAoC,CAAC,CAAC;AAiBnD,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;AAeD,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,uBAAuB,CAAS;IACxC,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;IAkCrB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;YAerB,QAAQ;YAoDR,KAAK;YAsFL,qBAAqB;YAkCrB,qBAAqB;IAuDnC,OAAO,CAAC,iBAAiB;YAgCX,kBAAkB;YAkClB,WAAW;IAqFzB,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"}
@@ -1,5 +1,5 @@
1
1
  import { randomUUID } from "node:crypto";
2
- import { acquireServicesRetainedNodeRecipientMessage, consumeServicesRetainedNodeRecipientMessage, heartbeatRuntimeEndpoint, RuntimeAdapterApiError, registerRuntimeEndpoint, unregisterRuntimeEndpoint, } from "./_vendor/runtime-adapter-client/index.js";
2
+ import { acquireServicesRetainedNodeRecipientMessage, consumeServicesRetainedNodeRecipientMessage, heartbeatRuntimeEndpoint, RuntimeAdapterApiError, registerRuntimeEndpoint, replyServicesRetainedNodeRecipientMessage, unregisterRuntimeEndpoint, } from "./_vendor/runtime-adapter-client/index.js";
3
3
  const RETRY_DELAY_MS = 5_000;
4
4
  const MIN_HEARTBEAT_DELAY_MS = 1_000;
5
5
  export class ServicesRetainedRecipientConsumer {
@@ -14,6 +14,7 @@ export class ServicesRetainedRecipientConsumer {
14
14
  presentedOffer = null;
15
15
  acquirePermanentlyBlocked = false;
16
16
  consumptionPermanentlyBlocked = false;
17
+ replyPermanentlyBlocked = false;
17
18
  consecutiveHeartbeatNotFound = 0;
18
19
  stopped = true;
19
20
  activationPromise = null;
@@ -73,6 +74,7 @@ export class ServicesRetainedRecipientConsumer {
73
74
  this.presentedOffer = null;
74
75
  this.acquirePermanentlyBlocked = false;
75
76
  this.consumptionPermanentlyBlocked = false;
77
+ this.replyPermanentlyBlocked = false;
76
78
  });
77
79
  return this.stopPromise;
78
80
  }
@@ -139,9 +141,11 @@ export class ServicesRetainedRecipientConsumer {
139
141
  this.drainRequested = false;
140
142
  const endpoint = this.endpoint;
141
143
  if (this.presentedOffer) {
142
- if (this.consumptionPermanentlyBlocked)
144
+ if (this.consumptionPermanentlyBlocked ||
145
+ this.replyPermanentlyBlocked) {
143
146
  return;
144
- if (!(await this.consumePresentedOffer(endpoint)))
147
+ }
148
+ if (!(await this.advancePresentedOffer(endpoint)))
145
149
  return;
146
150
  continue;
147
151
  }
@@ -174,29 +178,65 @@ export class ServicesRetainedRecipientConsumer {
174
178
  }
175
179
  return;
176
180
  }
181
+ const offer = {
182
+ messageRef: acquired.message_ref,
183
+ replyHandle: acquired.reply_handle,
184
+ consumed: false,
185
+ replyAttempt: null,
186
+ };
187
+ this.presentedOffer = offer;
188
+ this.consumptionPermanentlyBlocked = false;
189
+ this.replyPermanentlyBlocked = false;
177
190
  let presented = false;
178
191
  try {
179
192
  presented = await this.present({
180
193
  contentType: acquired.content_type,
181
194
  envelope: acquired.envelope,
195
+ reply: this.createReplyAction(offer),
182
196
  });
183
197
  }
184
198
  catch (error) {
185
199
  this.logger.error(`OpenClaw inbound presentation failed message_ref=${acquired.message_ref}`, error);
186
200
  }
187
201
  if (!presented) {
202
+ if (this.presentedOffer === offer)
203
+ this.presentedOffer = null;
188
204
  this.scheduleDrainRetry();
189
205
  return;
190
206
  }
191
- this.presentedOffer = {
192
- messageRef: acquired.message_ref,
193
- replyHandle: acquired.reply_handle,
194
- };
195
- this.consumptionPermanentlyBlocked = false;
196
- if (!(await this.consumePresentedOffer(endpoint)))
207
+ if (!(await this.advancePresentedOffer(endpoint)))
197
208
  return;
198
209
  }
199
210
  }
211
+ async advancePresentedOffer(endpoint) {
212
+ const offer = this.presentedOffer;
213
+ if (!offer)
214
+ return true;
215
+ if (!offer.consumed && !(await this.consumePresentedOffer(endpoint))) {
216
+ return false;
217
+ }
218
+ if (this.presentedOffer !== offer)
219
+ return true;
220
+ if (!offer.replyAttempt) {
221
+ this.presentedOffer = null;
222
+ this.drainRequested = true;
223
+ return true;
224
+ }
225
+ const result = await this.submitReplyAttempt(endpoint, offer);
226
+ if (result.status === "sent") {
227
+ this.presentedOffer = null;
228
+ this.replyPermanentlyBlocked = false;
229
+ this.drainRequested = true;
230
+ return true;
231
+ }
232
+ this.logger.error(`Services-retained reply refused message_ref=${offer.messageRef} code=${result.errorCode} retryable=${String(result.retryable)}`);
233
+ if (result.retryable) {
234
+ this.scheduleDrainRetry();
235
+ return false;
236
+ }
237
+ this.replyPermanentlyBlocked = true;
238
+ return false;
239
+ }
200
240
  async consumePresentedOffer(endpoint) {
201
241
  const offer = this.presentedOffer;
202
242
  if (!offer)
@@ -211,9 +251,8 @@ export class ServicesRetainedRecipientConsumer {
211
251
  });
212
252
  if (outcome.ok) {
213
253
  this.logger.info(`Services-retained message consumed message_ref=${offer.messageRef} status=${outcome.status}`);
214
- this.presentedOffer = null;
254
+ offer.consumed = true;
215
255
  this.consumptionPermanentlyBlocked = false;
216
- this.drainRequested = true;
217
256
  return true;
218
257
  }
219
258
  const reason = "providerStatus" in outcome ? outcome.reason : undefined;
@@ -236,6 +275,124 @@ export class ServicesRetainedRecipientConsumer {
236
275
  this.logger.error(`Services-retained consumption stopped on permanent rejection message_ref=${offer.messageRef}${reason ? ` reason=${reason}` : ""}`);
237
276
  return false;
238
277
  }
278
+ createReplyAction(offer) {
279
+ return async (content) => {
280
+ if (this.presentedOffer !== offer) {
281
+ return {
282
+ status: "failed",
283
+ errorCode: "reply_handle_stale",
284
+ error: "Services-retained reply authority is no longer active",
285
+ retryable: false,
286
+ };
287
+ }
288
+ if (offer.replyAttempt && offer.replyAttempt.content !== content) {
289
+ return {
290
+ status: "failed",
291
+ errorCode: "reply_handle_conflict",
292
+ error: "Services-retained reply authority was already used with different content",
293
+ retryable: false,
294
+ };
295
+ }
296
+ offer.replyAttempt ??= {
297
+ content,
298
+ requestId: randomUUID(),
299
+ inFlight: null,
300
+ terminalResult: null,
301
+ };
302
+ return { status: "staged" };
303
+ };
304
+ }
305
+ async submitReplyAttempt(endpoint, offer) {
306
+ const attempt = offer.replyAttempt;
307
+ if (!attempt) {
308
+ return {
309
+ status: "failed",
310
+ errorCode: "reply_unavailable",
311
+ error: "Services-retained reply content was not staged",
312
+ retryable: false,
313
+ };
314
+ }
315
+ if (attempt.terminalResult)
316
+ return attempt.terminalResult;
317
+ if (attempt.inFlight)
318
+ return attempt.inFlight;
319
+ attempt.inFlight = this.submitReply(endpoint, offer.replyHandle, attempt.requestId, attempt.content).then((result) => {
320
+ if (result.status === "sent" || !result.retryable) {
321
+ attempt.terminalResult = result;
322
+ }
323
+ return result;
324
+ });
325
+ try {
326
+ return await attempt.inFlight;
327
+ }
328
+ finally {
329
+ attempt.inFlight = null;
330
+ }
331
+ }
332
+ async submitReply(endpoint, replyHandle, replyRequestId, content) {
333
+ let failure;
334
+ for (let attempt = 0; attempt < 2; attempt++) {
335
+ let outcome;
336
+ try {
337
+ outcome = await replyServicesRetainedNodeRecipientMessage(this.clientConfig, this.runtimeKey, {
338
+ type: "runtime_node_recipient_message_reply",
339
+ version: 1,
340
+ endpoint_id: endpoint.id,
341
+ endpoint_nonce: endpoint.nonce,
342
+ reply_handle: replyHandle,
343
+ reply_request_id: replyRequestId,
344
+ content,
345
+ content_type: "text/plain",
346
+ });
347
+ }
348
+ catch (error) {
349
+ const errorCode = error instanceof RuntimeAdapterApiError
350
+ ? error.code
351
+ : "services_retained_reply_failed";
352
+ return {
353
+ status: "failed",
354
+ errorCode,
355
+ error: errorText(error),
356
+ retryable: false,
357
+ };
358
+ }
359
+ if (outcome.ok) {
360
+ this.logger.info(`Services-retained reply ${outcome.status} message_ref=${outcome.messageRef}`);
361
+ return {
362
+ status: "sent",
363
+ messageRef: outcome.messageRef,
364
+ replayed: outcome.status === "already_emitted",
365
+ };
366
+ }
367
+ failure = outcome;
368
+ if (outcome.terminal || attempt === 1)
369
+ break;
370
+ }
371
+ if (!failure) {
372
+ return {
373
+ status: "failed",
374
+ errorCode: "services_retained_reply_failed",
375
+ error: "Services-retained reply did not produce an outcome",
376
+ retryable: false,
377
+ };
378
+ }
379
+ const reason = "reason" in failure && typeof failure.reason === "string"
380
+ ? failure.reason
381
+ : "assignmentFailureCategory" in failure
382
+ ? failure.assignmentFailureCategory
383
+ : undefined;
384
+ const errorCode = reason ?? "services_retained_reply_failed";
385
+ const detail = "detail" in failure && typeof failure.detail === "string"
386
+ ? failure.detail
387
+ : errorCode;
388
+ this.logger.warn(`Services-retained reply failed code=${errorCode} terminal=${String(failure.terminal)} detail=${detail}`);
389
+ return {
390
+ status: "failed",
391
+ errorCode,
392
+ error: detail,
393
+ retryable: !failure.terminal,
394
+ };
395
+ }
239
396
  scheduleHeartbeat() {
240
397
  this.clearHeartbeatTimer();
241
398
  if (this.stopped || !this.endpoint)
@@ -0,0 +1,3 @@
1
+ export declare function runWithServicesRetainedReplyContext<T>(callback: () => T): T;
2
+ export declare function isServicesRetainedReplyContext(): boolean;
3
+ //# sourceMappingURL=services-retained-reply-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"services-retained-reply-context.d.ts","sourceRoot":"","sources":["../src/services-retained-reply-context.ts"],"names":[],"mappings":"AAIA,wBAAgB,mCAAmC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAE3E;AAED,wBAAgB,8BAA8B,IAAI,OAAO,CAExD"}
@@ -0,0 +1,8 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ const servicesRetainedReplyContext = new AsyncLocalStorage();
3
+ export function runWithServicesRetainedReplyContext(callback) {
4
+ return servicesRetainedReplyContext.run(true, callback);
5
+ }
6
+ export function isServicesRetainedReplyContext() {
7
+ return servicesRetainedReplyContext.getStore() === true;
8
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAuEA,UAAU,WAAW;IACnB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,CACP,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,WAAW,CAAC,CAAC;CAC3B;AAED,UAAU,WAAW;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,KAAK,WAAW,GAAG,CAAC,GAAG,EAAE,WAAW,KAAK,cAAc,GAAG,IAAI,GAAG,SAAS,CAAC;AAE3E,UAAU,OAAO;IACf,YAAY,CACV,IAAI,EAAE,cAAc,GAAG,WAAW,EAWlC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAC7D,IAAI,CAAC;CACT;AAoDD,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C;AAwSD,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAs2BhD"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAwEA,UAAU,WAAW;IACnB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,CACP,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,WAAW,CAAC,CAAC;CAC3B;AAED,UAAU,WAAW;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,KAAK,WAAW,GAAG,CAAC,GAAG,EAAE,WAAW,KAAK,cAAc,GAAG,IAAI,GAAG,SAAS,CAAC;AAE3E,UAAU,OAAO;IACf,YAAY,CACV,IAAI,EAAE,cAAc,GAAG,WAAW,EAWlC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAC7D,IAAI,CAAC;CACT;AAoDD,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C;AAwSD,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CA22BhD"}
package/dist/tools.js CHANGED
@@ -7,6 +7,7 @@ import { extractHandleFromAddress } from "./handle-utils.js";
7
7
  import { ownerNotesQueue } from "./owner-notes.js";
8
8
  import { acceptRequest, declineRequest, listConnections, listRequests, PlatformApiError, PlatformNetworkError, requestConnection, updateProfile, } from "./platform-client.js";
9
9
  import { sentMessageBuffer } from "./sent-message-buffer.js";
10
+ import { isServicesRetainedReplyContext } from "./services-retained-reply-context.js";
10
11
  import { getCurrentTurnChannelId, getCurrentTurnIsOwnerNonConsuming, getCurrentTurnOwnerSignal, } from "./turn-context.js";
11
12
  import { getLatestPublishedVersion, getPluginVersion, getUpdateInfo, } from "./update-check.js";
12
13
  const PROFILE_FIELDS = new Set(["name", "scope", "about", "audience"]);
@@ -584,6 +585,9 @@ export function registerTools(api) {
584
585
  }),
585
586
  }),
586
587
  execute: withUpdateNotice(async (_id, params) => {
588
+ if (isServicesRetainedReplyContext()) {
589
+ return textResult("This Services-retained message must be answered with an ordinary plain-text reply. The Host will apply its opaque reply authority; masons_send_message cannot be used as a fallback for this turn.");
590
+ }
587
591
  const cm = requireConversationManager();
588
592
  const to = params.to;
589
593
  const content = params.content;
@@ -1,13 +1,11 @@
1
1
  import type { OwnerSignal } from "./owner-session-state.js";
2
2
  export declare function setCurrentTurnSender(contact: string | null): void;
3
3
  export declare function setCurrentTurnSenderAddress(address: string | null): void;
4
- export declare function setCurrentTurnReplyRoute(route: "routable" | "unavailable"): void;
5
4
  export declare function setCurrentTurnChannelId(channelId: string | null): void;
6
5
  export declare function setCurrentTurnIsOwnerForTools(value: boolean): void;
7
6
  export declare function setCurrentTurnOwnerSignalForTools(signal: OwnerSignal): void;
8
7
  export declare function consumeCurrentTurnSender(): string | null;
9
8
  export declare function consumeCurrentTurnSenderAddress(): string | null;
10
- export declare function consumeCurrentTurnReplyRoute(): "routable" | "unavailable" | null;
11
9
  export declare function getCurrentTurnChannelId(): string | null;
12
10
  export declare function getCurrentTurnIsOwnerNonConsuming(): boolean;
13
11
  export declare function getCurrentTurnOwnerSignal(): OwnerSignal;
@@ -1 +1 @@
1
- {"version":3,"file":"turn-context.d.ts","sourceRoot":"","sources":["../src/turn-context.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AA0C5D,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEjE;AAUD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAExE;AAGD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,UAAU,GAAG,aAAa,GAChC,IAAI,CAEN;AAOD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEtE;AAOD,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAElE;AAUD,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAE3E;AAUD,wBAAgB,wBAAwB,IAAI,MAAM,GAAG,IAAI,CAIxD;AAGD,wBAAgB,+BAA+B,IAAI,MAAM,GAAG,IAAI,CAI/D;AAGD,wBAAgB,4BAA4B,IACxC,UAAU,GACV,aAAa,GACb,IAAI,CAIP;AAMD,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,IAAI,CAEvD;AAMD,wBAAgB,iCAAiC,IAAI,OAAO,CAE3D;AAOD,wBAAgB,yBAAyB,IAAI,WAAW,CAEvD"}
1
+ {"version":3,"file":"turn-context.d.ts","sourceRoot":"","sources":["../src/turn-context.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAyC5D,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEjE;AAUD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAExE;AAOD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEtE;AAOD,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAElE;AAUD,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAE3E;AAUD,wBAAgB,wBAAwB,IAAI,MAAM,GAAG,IAAI,CAIxD;AAGD,wBAAgB,+BAA+B,IAAI,MAAM,GAAG,IAAI,CAI/D;AAMD,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,IAAI,CAEvD;AAMD,wBAAgB,iCAAiC,IAAI,OAAO,CAE3D;AAOD,wBAAgB,yBAAyB,IAAI,WAAW,CAEvD"}
@@ -1,6 +1,5 @@
1
1
  let currentTurnSender = null;
2
2
  let currentTurnSenderAddress = null;
3
- let currentTurnReplyRoute = null;
4
3
  let currentTurnChannelId = null;
5
4
  let currentTurnIsOwner = false;
6
5
  let currentTurnOwnerSignalForTools = null;
@@ -10,9 +9,6 @@ export function setCurrentTurnSender(contact) {
10
9
  export function setCurrentTurnSenderAddress(address) {
11
10
  currentTurnSenderAddress = address;
12
11
  }
13
- export function setCurrentTurnReplyRoute(route) {
14
- currentTurnReplyRoute = route;
15
- }
16
12
  export function setCurrentTurnChannelId(channelId) {
17
13
  currentTurnChannelId = channelId;
18
14
  }
@@ -32,11 +28,6 @@ export function consumeCurrentTurnSenderAddress() {
32
28
  currentTurnSenderAddress = null;
33
29
  return value;
34
30
  }
35
- export function consumeCurrentTurnReplyRoute() {
36
- const value = currentTurnReplyRoute;
37
- currentTurnReplyRoute = null;
38
- return value;
39
- }
40
31
  export function getCurrentTurnChannelId() {
41
32
  return currentTurnChannelId;
42
33
  }
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const PLUGIN_VERSION = "0.6.17";
1
+ export declare const PLUGIN_VERSION = "0.6.18";
2
2
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const PLUGIN_VERSION = "0.6.17";
1
+ export const PLUGIN_VERSION = "0.6.18";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@masons/agent-network",
3
- "version": "0.6.17",
3
+ "version": "0.6.18",
4
4
  "description": "MASONS Agent Network — OpenClaw channel plugin for connecting agent runtimes to the Agent Network over MSTP.",
5
5
  "license": "MIT",
6
6
  "author": "MASONS.ai <hello@masons.ai> (https://masons.ai)",