@masons/agent-network 0.5.14 → 0.5.16

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 (66) hide show
  1. package/dist/channel.d.ts +0 -7
  2. package/dist/channel.d.ts.map +1 -1
  3. package/dist/channel.js +3 -174
  4. package/dist/cli-setup.d.ts +0 -109
  5. package/dist/cli-setup.d.ts.map +1 -1
  6. package/dist/cli-setup.js +16 -570
  7. package/dist/config-fs.d.ts +4 -0
  8. package/dist/config-fs.d.ts.map +1 -0
  9. package/dist/config-fs.js +23 -0
  10. package/dist/config-schema.js +2 -2
  11. package/dist/config.d.ts +2 -210
  12. package/dist/config.d.ts.map +1 -1
  13. package/dist/config.js +14 -334
  14. package/dist/connector-client.d.ts +0 -32
  15. package/dist/connector-client.d.ts.map +1 -1
  16. package/dist/connector-client.js +1 -89
  17. package/dist/constants.d.ts +0 -1
  18. package/dist/constants.d.ts.map +1 -1
  19. package/dist/constants.js +2 -3
  20. package/dist/conversation-manager.d.ts +0 -106
  21. package/dist/conversation-manager.d.ts.map +1 -1
  22. package/dist/conversation-manager.js +2 -131
  23. package/dist/environment-context.d.ts +0 -24
  24. package/dist/environment-context.d.ts.map +1 -1
  25. package/dist/environment-context.js +0 -42
  26. package/dist/handle-utils.d.ts +0 -14
  27. package/dist/handle-utils.d.ts.map +1 -1
  28. package/dist/handle-utils.js +0 -14
  29. package/dist/index.js +0 -9
  30. package/dist/owner-notes.d.ts +0 -33
  31. package/dist/owner-notes.d.ts.map +1 -1
  32. package/dist/owner-notes.js +2 -41
  33. package/dist/owner-session-state.d.ts +0 -26
  34. package/dist/owner-session-state.d.ts.map +1 -1
  35. package/dist/owner-session-state.js +0 -37
  36. package/dist/platform-client.d.ts +13 -202
  37. package/dist/platform-client.d.ts.map +1 -1
  38. package/dist/platform-client.js +22 -171
  39. package/dist/plugin.d.ts +5 -0
  40. package/dist/plugin.d.ts.map +1 -1
  41. package/dist/plugin.js +3 -167
  42. package/dist/sent-message-buffer.d.ts +0 -36
  43. package/dist/sent-message-buffer.d.ts.map +1 -1
  44. package/dist/sent-message-buffer.js +1 -45
  45. package/dist/tools.d.ts +0 -28
  46. package/dist/tools.d.ts.map +1 -1
  47. package/dist/tools.js +36 -240
  48. package/dist/turn-context.d.ts +0 -45
  49. package/dist/turn-context.d.ts.map +1 -1
  50. package/dist/turn-context.js +0 -57
  51. package/dist/types.d.ts +0 -67
  52. package/dist/types.d.ts.map +1 -1
  53. package/dist/types.js +0 -7
  54. package/dist/update-cache.d.ts +0 -17
  55. package/dist/update-cache.d.ts.map +1 -1
  56. package/dist/update-cache.js +1 -21
  57. package/dist/update-check.d.ts +1 -40
  58. package/dist/update-check.d.ts.map +1 -1
  59. package/dist/update-check.js +7 -66
  60. package/dist/version.d.ts +1 -2
  61. package/dist/version.d.ts.map +1 -1
  62. package/dist/version.js +1 -2
  63. package/openclaw.plugin.json +94 -3
  64. package/package.json +11 -10
  65. package/skills/agent-network/SKILL.md +21 -47
  66. package/skills/agent-network/references/troubleshooting.md +5 -5
@@ -1,23 +1,7 @@
1
- /**
2
- * Conversation Manager — maps contacts to conversations.
3
- *
4
- * Owns the identity-based API that the Tool Interface and Inbound Dispatcher
5
- * call. Sends messages directly to routable addresses via ConnectorClient.send().
6
- *
7
- * Contact resolution: handle → `mstps://${connectorHost}/${handle}`
8
- * Address schemes: MSTP (`mstps://`), handle (bare), passport (`passport:@`)
9
- * Internal key: routable address.
10
- * One conversation per contact, in-memory only (D3).
11
- *
12
- * @see docs/connector/gateway-v2-consumer-adaptation-plan.md PR 2
13
- */
14
1
  import createDebug from "debug";
15
2
  import { ConnectorError } from "./connector-client.js";
16
3
  import { extractHandleFromAddress } from "./handle-utils.js";
17
4
  const dbg = createDebug("agent-network:conversation-manager");
18
- // ---------------------------------------------------------------------------
19
- // Error code → tool result mapping
20
- // ---------------------------------------------------------------------------
21
5
  const ERROR_MESSAGES = {
22
6
  ADDRESS_NOT_FOUND: "Cannot find agent '{to}'. Check the handle.",
23
7
  ACCESS_DENIED: "No connection to '{to}'. Send a connection request first.",
@@ -29,50 +13,19 @@ function formatErrorMessage(code, to) {
29
13
  const template = ERROR_MESSAGES[code] ?? `Send failed: ${code}`;
30
14
  return to ? template.replace(/\{to\}/g, to) : template;
31
15
  }
32
- // ---------------------------------------------------------------------------
33
- // ConversationManager
34
- // ---------------------------------------------------------------------------
35
16
  export class ConversationManager {
36
17
  client;
37
18
  connectorHost;
38
- /** Conversations keyed by routable address */
39
19
  conversations = new Map();
40
20
  constructor(client, connectorHost) {
41
21
  this.client = client;
42
22
  this.connectorHost = connectorHost;
43
23
  }
44
- // -------------------------------------------------------------------------
45
- // Public API — identity-based
46
- // -------------------------------------------------------------------------
47
- /**
48
- * Send a message to a contact. Sends directly to the resolved address —
49
- * no session management needed.
50
- *
51
- * Returns a structured result with status and optional error.
52
- * ConnectorError codes (ADDRESS_NOT_FOUND, ACCESS_DENIED, etc.) are
53
- * mapped to human-readable messages for LLM tool results.
54
- *
55
- * @param contact - Handle, MSTP address, or passport address of the target.
56
- * @param content - Message content to send.
57
- */
58
24
  async send(contact, content) {
59
25
  const address = this.resolveAddress(contact);
60
- // Ensure conversation entry exists
61
- if (!this.conversations.has(address)) {
62
- this.conversations.set(address, {
63
- contact: this.extractHandle(address),
64
- address,
65
- lastMessageAt: Date.now(),
66
- initiatedBy: "local",
67
- });
68
- }
69
26
  try {
70
27
  const ack = await this.client.send(address, content, "text");
71
- // Update lastMessageAt
72
- const entry = this.conversations.get(address);
73
- if (entry) {
74
- entry.lastMessageAt = Date.now();
75
- }
28
+ this.ensureConversationEntry(this.extractHandle(address), address, "local");
76
29
  dbg("send contact=%s address=%s status=%s", contact, address, ack.status);
77
30
  return { status: "sent" };
78
31
  }
@@ -87,35 +40,20 @@ export class ConversationManager {
87
40
  return { status: "failed", error: message };
88
41
  }
89
42
  }
90
- /**
91
- * Register an inbound conversation (remote agent or visitor initiated).
92
- * Called by the channel adapter when a message arrives from a new address.
93
- */
94
43
  registerInbound(contact, address) {
95
44
  this.ensureConversationEntry(contact, address, "remote");
96
45
  dbg("registerInbound contact=%s address=%s", contact, address);
97
46
  }
98
- /**
99
- * Resolve a routable address to a contact handle.
100
- * Used by the inbound dispatcher to derive sender identity from MESSAGE_RECEIVED.from.
101
- */
102
47
  getContactByAddress(address) {
103
48
  const entry = this.conversations.get(address);
104
49
  if (entry)
105
50
  return entry.contact;
106
- // Try resolving — the address might be a full MSTP address while conversations
107
- // are keyed by a different form. Extract handle as fallback.
108
51
  for (const [, e] of this.conversations) {
109
52
  if (e.address === address)
110
53
  return e.contact;
111
54
  }
112
55
  return undefined;
113
56
  }
114
- /**
115
- * List all conversations with metadata.
116
- * `active` is always true for address-based protocol — there is no session
117
- * lifecycle. Conversations persist until explicitly ended or Plugin restarts.
118
- */
119
57
  listConversations() {
120
58
  const result = [];
121
59
  for (const [, entry] of this.conversations) {
@@ -129,32 +67,10 @@ export class ConversationManager {
129
67
  }
130
68
  return result;
131
69
  }
132
- /**
133
- * Check if a conversation entry exists for a contact.
134
- *
135
- * Returns true for entries that are marked `ended` but not yet committed —
136
- * this allows the deliver callback to flush buffered text from the same
137
- * dispatch cycle as end_conversation (#999).
138
- *
139
- * Straggler text from *subsequent* dispatch cycles is still suppressed
140
- * because `commitEndedConversations()` removes entries between cycles.
141
- */
142
70
  hasConversation(contact) {
143
71
  const address = this.resolveAddress(contact);
144
72
  return this.conversations.has(address);
145
73
  }
146
- /**
147
- * Mark the conversation with a contact as ended (deferred deletion).
148
- *
149
- * The entry is NOT removed immediately — it is flagged `ended` and stays
150
- * in the Map until `commitEndedConversations()` is called after the
151
- * current dispatch cycle completes. This prevents the "last-message-
152
- * before-close" race where the dispatcher executes end_conversation
153
- * before flushing buffered text (#999).
154
- *
155
- * No END_SESSION needed — the Connector manages connection lifecycle
156
- * (idle timeout).
157
- */
158
74
  endConversation(contact) {
159
75
  const address = this.resolveAddress(contact);
160
76
  const entry = this.conversations.get(address);
@@ -166,19 +82,6 @@ export class ConversationManager {
166
82
  dbg("endConversation (no-op) contact=%s address=%s", contact, address);
167
83
  }
168
84
  }
169
- /**
170
- * Remove all conversations marked as `ended`.
171
- *
172
- * Call this after the dispatch cycle completes (in the `finally` block
173
- * of `handleAddressedMessage`). Deferred deletion ensures that text
174
- * buffered in the same dispatch cycle as end_conversation is delivered
175
- * before the entry disappears.
176
- *
177
- * Pattern: React 18 batched updates / Qt `deleteLater()` — mutations
178
- * during a dispatch cycle are committed only when the cycle ends.
179
- *
180
- * @see https://github.com/MASONS-ai/masons.ai/issues/999
181
- */
182
85
  commitEndedConversations() {
183
86
  let count = 0;
184
87
  for (const [address, entry] of this.conversations) {
@@ -191,23 +94,6 @@ export class ConversationManager {
191
94
  dbg("commitEndedConversations removed=%d", count);
192
95
  }
193
96
  }
194
- // -------------------------------------------------------------------------
195
- // Contact resolution
196
- // -------------------------------------------------------------------------
197
- /**
198
- * Resolve a contact (handle, MSTP address, or passport address) to a
199
- * routable address.
200
- *
201
- * Resolution order:
202
- * 1. MSTP address (starts with mstps:// or mstp://) → return as-is.
203
- * 2. Passport address (starts with passport:) → return as-is (already routable).
204
- * 3. Already a key in the conversations map → return as-is.
205
- * 4. Reverse lookup: if any existing conversation has this handle as its
206
- * contact, use that conversation's address. This ensures replies to a
207
- * cross-Connector sender route to the sender's original address, not to
208
- * a locally-constructed address.
209
- * 5. Otherwise treat as handle → construct `mstps://${connectorHost}/${handle}`.
210
- */
211
97
  resolveAddress(contact) {
212
98
  if (contact.startsWith("mstps://") || contact.startsWith("mstp://")) {
213
99
  return contact;
@@ -218,26 +104,15 @@ export class ConversationManager {
218
104
  if (this.conversations.has(contact)) {
219
105
  return contact;
220
106
  }
221
- // Reverse lookup: handle → existing conversation address.
222
- // Handles the case where inbound arrived from a remote Connector
223
- // (e.g., "mstps://remote-host/mason") but the LLM replies using
224
- // the bare handle "mason".
225
107
  for (const [addr, entry] of this.conversations) {
226
108
  if (entry.contact === contact)
227
109
  return addr;
228
110
  }
229
111
  return `mstps://${this.connectorHost}/${contact}`;
230
112
  }
231
- /**
232
- * Extract a display-friendly handle from any address scheme.
233
- * Delegates to shared utility — single source of truth.
234
- */
235
113
  extractHandle(address) {
236
114
  return extractHandleFromAddress(address);
237
115
  }
238
- // -------------------------------------------------------------------------
239
- // Internal
240
- // -------------------------------------------------------------------------
241
116
  ensureConversationEntry(contact, address, initiatedBy) {
242
117
  if (!this.conversations.has(address)) {
243
118
  this.conversations.set(address, {
@@ -251,14 +126,10 @@ export class ConversationManager {
251
126
  const entry = this.conversations.get(address);
252
127
  if (entry) {
253
128
  entry.lastMessageAt = Date.now();
254
- entry.ended = false; // Clear deferred deletion on re-registration
129
+ entry.ended = false;
255
130
  }
256
131
  }
257
132
  }
258
- // -------------------------------------------------------------------------
259
- // Test helpers
260
- // -------------------------------------------------------------------------
261
- /** @internal Reset for test isolation. */
262
133
  _resetForTesting() {
263
134
  this.conversations.clear();
264
135
  }
@@ -1,18 +1,3 @@
1
- /**
2
- * Agent Environment Context — self-identity and owner identity.
3
- *
4
- * Populated from REGISTER_ACK when the Connector includes agent/owner fields
5
- * (#969). Connection-scoped: cleared on disconnect, refreshed on reconnect.
6
- *
7
- * Module-level singleton — shared between connector-client.ts (write) and
8
- * plugin.ts (read). Follows the same pattern as owner-session-state.ts.
9
- *
10
- * **Trust model**: Identity is Connector-asserted, not cryptographically
11
- * verified. The Plugin trusts the Connector because they communicate over an
12
- * authenticated WebSocket channel. A self-hosted Connector could assert
13
- * arbitrary identity — this is the same trust level as the `from` field on
14
- * MESSAGE_RECEIVED. Do not build security-critical logic on these values.
15
- */
16
1
  export interface AgentIdentity {
17
2
  handle: string;
18
3
  name?: string;
@@ -21,12 +6,6 @@ export interface OwnerIdentity {
21
6
  handle: string;
22
7
  displayName?: string;
23
8
  }
24
- /**
25
- * Store agent and owner identity from an enriched REGISTER_ACK.
26
- *
27
- * Either parameter may be undefined (old Connector, or agent without
28
- * a bound owner). Undefined values leave the corresponding state as null.
29
- */
30
9
  export declare function setEnvironmentContext(agent?: {
31
10
  handle: string;
32
11
  name?: string;
@@ -36,10 +15,7 @@ export declare function setEnvironmentContext(agent?: {
36
15
  }): void;
37
16
  export declare function getAgentIdentity(): AgentIdentity | null;
38
17
  export declare function getOwnerIdentity(): OwnerIdentity | null;
39
- /** Convenience: get the owner's handle (used by auto-link in channel.ts). */
40
18
  export declare function getOwnerHandle(): string | null;
41
- /** Clear all environment context (connection lost — identity invalid). */
42
19
  export declare function clearEnvironmentContext(): void;
43
- /** @internal Reset module state for test isolation. */
44
20
  export declare function _resetForTesting(): void;
45
21
  //# sourceMappingURL=environment-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"environment-context.d.ts","sourceRoot":"","sources":["../src/environment-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAaD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,CAAC,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EACzC,KAAK,CAAC,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C,IAAI,CAkBN;AAMD,wBAAgB,gBAAgB,IAAI,aAAa,GAAG,IAAI,CAEvD;AAED,wBAAgB,gBAAgB,IAAI,aAAa,GAAG,IAAI,CAEvD;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAE9C;AAMD,0EAA0E;AAC1E,wBAAgB,uBAAuB,IAAI,IAAI,CAG9C;AAMD,uDAAuD;AACvD,wBAAgB,gBAAgB,IAAI,IAAI,CAGvC"}
1
+ {"version":3,"file":"environment-context.d.ts","sourceRoot":"","sources":["../src/environment-context.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAmBD,wBAAgB,qBAAqB,CACnC,KAAK,CAAC,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EACzC,KAAK,CAAC,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C,IAAI,CAkBN;AAMD,wBAAgB,gBAAgB,IAAI,aAAa,GAAG,IAAI,CAEvD;AAED,wBAAgB,gBAAgB,IAAI,aAAa,GAAG,IAAI,CAEvD;AAGD,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAE9C;AAOD,wBAAgB,uBAAuB,IAAI,IAAI,CAG9C;AAOD,wBAAgB,gBAAgB,IAAI,IAAI,CAGvC"}
@@ -1,36 +1,6 @@
1
- /**
2
- * Agent Environment Context — self-identity and owner identity.
3
- *
4
- * Populated from REGISTER_ACK when the Connector includes agent/owner fields
5
- * (#969). Connection-scoped: cleared on disconnect, refreshed on reconnect.
6
- *
7
- * Module-level singleton — shared between connector-client.ts (write) and
8
- * plugin.ts (read). Follows the same pattern as owner-session-state.ts.
9
- *
10
- * **Trust model**: Identity is Connector-asserted, not cryptographically
11
- * verified. The Plugin trusts the Connector because they communicate over an
12
- * authenticated WebSocket channel. A self-hosted Connector could assert
13
- * arbitrary identity — this is the same trust level as the `from` field on
14
- * MESSAGE_RECEIVED. Do not build security-critical logic on these values.
15
- */
16
- // ---------------------------------------------------------------------------
17
- // State
18
- // ---------------------------------------------------------------------------
19
1
  let agentIdentity = null;
20
2
  let ownerIdentity = null;
21
- // ---------------------------------------------------------------------------
22
- // Write API (called from connector-client.ts on REGISTER_ACK)
23
- // ---------------------------------------------------------------------------
24
- /**
25
- * Store agent and owner identity from an enriched REGISTER_ACK.
26
- *
27
- * Either parameter may be undefined (old Connector, or agent without
28
- * a bound owner). Undefined values leave the corresponding state as null.
29
- */
30
3
  export function setEnvironmentContext(agent, owner) {
31
- // Defensive: validate handle is a string even though types say so.
32
- // A malformed REGISTER_ACK from an untrusted Connector could send
33
- // non-string values; guard prevents storing garbage in module state.
34
4
  if (agent && typeof agent.handle === "string") {
35
5
  const identity = { handle: agent.handle };
36
6
  if (agent.name)
@@ -50,31 +20,19 @@ export function setEnvironmentContext(agent, owner) {
50
20
  ownerIdentity = null;
51
21
  }
52
22
  }
53
- // ---------------------------------------------------------------------------
54
- // Read API (called from plugin.ts in before_prompt_build)
55
- // ---------------------------------------------------------------------------
56
23
  export function getAgentIdentity() {
57
24
  return agentIdentity;
58
25
  }
59
26
  export function getOwnerIdentity() {
60
27
  return ownerIdentity;
61
28
  }
62
- /** Convenience: get the owner's handle (used by auto-link in channel.ts). */
63
29
  export function getOwnerHandle() {
64
30
  return ownerIdentity?.handle ?? null;
65
31
  }
66
- // ---------------------------------------------------------------------------
67
- // Lifecycle
68
- // ---------------------------------------------------------------------------
69
- /** Clear all environment context (connection lost — identity invalid). */
70
32
  export function clearEnvironmentContext() {
71
33
  agentIdentity = null;
72
34
  ownerIdentity = null;
73
35
  }
74
- // ---------------------------------------------------------------------------
75
- // Test-only reset
76
- // ---------------------------------------------------------------------------
77
- /** @internal Reset module state for test isolation. */
78
36
  export function _resetForTesting() {
79
37
  agentIdentity = null;
80
38
  ownerIdentity = null;
@@ -1,16 +1,2 @@
1
- /**
2
- * Shared handle extraction utility.
3
- *
4
- * Used by ConversationManager (contact resolution) and Channel (sender name derivation).
5
- * Single source of truth for address → display handle mapping.
6
- */
7
- /**
8
- * Extract a display-friendly handle from any address scheme.
9
- *
10
- * - `mstps://preview.masons.ai/alice` → `alice`
11
- * - `passport:@luomingke` → `luomingke`
12
- * - `passport:user_abc` → `user_abc`
13
- * - `mason` → `mason` (bare handle passthrough)
14
- */
15
1
  export declare function extractHandleFromAddress(address: string): string;
16
2
  //# sourceMappingURL=handle-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handle-utils.d.ts","sourceRoot":"","sources":["../src/handle-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAUhE"}
1
+ {"version":3,"file":"handle-utils.d.ts","sourceRoot":"","sources":["../src/handle-utils.ts"],"names":[],"mappings":"AAeA,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAUhE"}
@@ -1,17 +1,3 @@
1
- /**
2
- * Shared handle extraction utility.
3
- *
4
- * Used by ConversationManager (contact resolution) and Channel (sender name derivation).
5
- * Single source of truth for address → display handle mapping.
6
- */
7
- /**
8
- * Extract a display-friendly handle from any address scheme.
9
- *
10
- * - `mstps://preview.masons.ai/alice` → `alice`
11
- * - `passport:@luomingke` → `luomingke`
12
- * - `passport:user_abc` → `user_abc`
13
- * - `mason` → `mason` (bare handle passthrough)
14
- */
15
1
  export function extractHandleFromAddress(address) {
16
2
  if (address.startsWith("passport:@")) {
17
3
  return address.slice("passport:@".length);
package/dist/index.js CHANGED
@@ -1,10 +1 @@
1
- // Main entry point for @masons/agent-network.
2
- //
3
- // This file MUST NOT import modules that depend on Node.js-only packages (ws,
4
- // etc.) because some consumers import from here in Next.js builds that include
5
- // client bundles.
6
- //
7
- // The OpenClaw Plugin entry is in ./plugin.ts (loaded via openclaw.extensions).
8
- // The ConnectorClient and protocol types are available via dedicated sub-exports.
9
- // --- Shared constants ---
10
1
  export { AUTHORIZED_TOKEN_TTL_MS, SETUP_CODE_CHARSET, SETUP_CODE_LENGTH, SETUP_CODE_TTL_MS, } from "./constants.js";
@@ -1,48 +1,15 @@
1
- /**
2
- * Owner Notes Queue — in-memory queue for Principal notifications.
3
- *
4
- * When the LLM receives information from a remote agent that the owner
5
- * should know about, it calls `masons_note_for_owner` which enqueues
6
- * a note here. The `before_prompt_build` hook drains the queue on the
7
- * owner's next turn and injects the notes into prependContext.
8
- *
9
- * Module-level singleton — shared between plugin.ts (drain) and tools.ts (enqueue).
10
- * Same pattern as Mkclaw's PendingEventsQueue (see ref_mkclaw_cross_session.md).
11
- *
12
- * Lifecycle: in-memory only. Lost on Gateway restart. Layer 2 (MASONS backend)
13
- * will add persistence — this queue is the Layer 1 implementation.
14
- *
15
- * @see docs/openclaw/interop-routing-system-design.md §7.1
16
- */
17
1
  export interface OwnerNote {
18
- /** The note content — summarized by the LLM. */
19
2
  content: string;
20
- /** When the note was created (Date.now()). */
21
3
  timestamp: number;
22
- /** Handle of the remote agent this note is about (e.g. "nikoko"). */
23
4
  from?: string;
24
5
  }
25
6
  export declare class OwnerNotesQueue {
26
7
  private notes;
27
8
  static readonly MAX_SIZE = 50;
28
9
  static readonly TTL_MS: number;
29
- /**
30
- * Enqueue a note. FIFO: if at MAX_SIZE after TTL eviction, drops oldest.
31
- * Always accepts the new note.
32
- */
33
10
  enqueue(note: OwnerNote): void;
34
- /**
35
- * Drain all non-stale notes. Destructive — drained notes are removed.
36
- * Returns notes in chronological order (oldest first).
37
- */
38
11
  drain(): OwnerNote[];
39
- /**
40
- * Current queue size (after TTL eviction).
41
- */
42
12
  size(): number;
43
- /**
44
- * Clear all notes. For testing only.
45
- */
46
13
  clear(): void;
47
14
  private evictStale;
48
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"owner-notes.d.ts","sourceRoot":"","sources":["../src/owner-notes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,MAAM,WAAW,SAAS;IACxB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAMD,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAmB;IAEhC,MAAM,CAAC,QAAQ,CAAC,QAAQ,MAAM;IAC9B,MAAM,CAAC,QAAQ,CAAC,MAAM,SAAuB;IAE7C;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAQ9B;;;OAGG;IACH,KAAK,IAAI,SAAS,EAAE;IAOpB;;OAEG;IACH,IAAI,IAAI,MAAM;IAKd;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb,OAAO,CAAC,UAAU;CAInB;AAMD,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
1
+ {"version":3,"file":"owner-notes.d.ts","sourceRoot":"","sources":["../src/owner-notes.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,SAAS;IAExB,OAAO,EAAE,MAAM,CAAC;IAEhB,SAAS,EAAE,MAAM,CAAC;IAElB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAMD,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAmB;IAEhC,MAAM,CAAC,QAAQ,CAAC,QAAQ,MAAM;IAC9B,MAAM,CAAC,QAAQ,CAAC,MAAM,SAAuB;IAM7C,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAY9B,KAAK,IAAI,SAAS,EAAE;IAUpB,IAAI,IAAI,MAAM;IAQd,KAAK,IAAI,IAAI;IAQb,OAAO,CAAC,UAAU;CAInB;AAMD,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
@@ -1,69 +1,30 @@
1
- /**
2
- * Owner Notes Queue — in-memory queue for Principal notifications.
3
- *
4
- * When the LLM receives information from a remote agent that the owner
5
- * should know about, it calls `masons_note_for_owner` which enqueues
6
- * a note here. The `before_prompt_build` hook drains the queue on the
7
- * owner's next turn and injects the notes into prependContext.
8
- *
9
- * Module-level singleton — shared between plugin.ts (drain) and tools.ts (enqueue).
10
- * Same pattern as Mkclaw's PendingEventsQueue (see ref_mkclaw_cross_session.md).
11
- *
12
- * Lifecycle: in-memory only. Lost on Gateway restart. Layer 2 (MASONS backend)
13
- * will add persistence — this queue is the Layer 1 implementation.
14
- *
15
- * @see docs/openclaw/interop-routing-system-design.md §7.1
16
- */
17
- // ---------------------------------------------------------------------------
18
- // Queue
19
- // ---------------------------------------------------------------------------
20
1
  export class OwnerNotesQueue {
21
2
  notes = [];
22
3
  static MAX_SIZE = 50;
23
- static TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
24
- /**
25
- * Enqueue a note. FIFO: if at MAX_SIZE after TTL eviction, drops oldest.
26
- * Always accepts the new note.
27
- */
4
+ static TTL_MS = 24 * 60 * 60 * 1000;
28
5
  enqueue(note) {
29
6
  this.evictStale();
30
7
  if (this.notes.length >= OwnerNotesQueue.MAX_SIZE) {
31
- this.notes.shift(); // drop oldest (FIFO)
8
+ this.notes.shift();
32
9
  }
33
10
  this.notes.push(note);
34
11
  }
35
- /**
36
- * Drain all non-stale notes. Destructive — drained notes are removed.
37
- * Returns notes in chronological order (oldest first).
38
- */
39
12
  drain() {
40
13
  this.evictStale();
41
14
  const drained = [...this.notes];
42
15
  this.notes = [];
43
16
  return drained;
44
17
  }
45
- /**
46
- * Current queue size (after TTL eviction).
47
- */
48
18
  size() {
49
19
  this.evictStale();
50
20
  return this.notes.length;
51
21
  }
52
- /**
53
- * Clear all notes. For testing only.
54
- */
55
22
  clear() {
56
23
  this.notes = [];
57
24
  }
58
- // -------------------------------------------------------------------------
59
- // Internal
60
- // -------------------------------------------------------------------------
61
25
  evictStale() {
62
26
  const cutoff = Date.now() - OwnerNotesQueue.TTL_MS;
63
27
  this.notes = this.notes.filter((n) => n.timestamp > cutoff);
64
28
  }
65
29
  }
66
- // ---------------------------------------------------------------------------
67
- // Singleton
68
- // ---------------------------------------------------------------------------
69
30
  export const ownerNotesQueue = new OwnerNotesQueue();
@@ -1,32 +1,6 @@
1
- /**
2
- * Owner Identity State — tracks which addresses belong to the agent's owner.
3
- *
4
- * When the Connector detects that a Passport visitor is the agent's owner
5
- * (deterministic userId comparison, #836), it includes `is_owner: true` in
6
- * MESSAGE_RECEIVED metadata. This module maintains the Plugin-side state:
7
- *
8
- * - `ownerAddresses`: Set of routable addresses where the visitor is the owner.
9
- * Populated on first MESSAGE_RECEIVED with is_owner=true, cleared on disconnect.
10
- *
11
- * - `currentTurnIsOwner`: Per-turn flag set in the message_received handler
12
- * and read in before_prompt_build. Reset after each read to avoid stale state.
13
- *
14
- * Module-level singleton — shared between channel.ts (write) and plugin.ts (read).
15
- */
16
- /** Mark an address as belonging to the owner. */
17
1
  export declare function markOwnerAddress(address: string): void;
18
- /** Check if an address belongs to the owner. */
19
2
  export declare function isOwnerAddress(address: string): boolean;
20
- /** Clear all owner state (connection lost — all addresses invalid). */
21
3
  export declare function clearOwnerState(): void;
22
- /**
23
- * Set the per-turn owner flag. Called in message_received before dispatch.
24
- * The flag is consumed (read + reset) by before_prompt_build.
25
- */
26
4
  export declare function setCurrentTurnIsOwner(value: boolean): void;
27
- /**
28
- * Consume the per-turn owner flag. Returns the value and resets to false.
29
- * Consuming prevents stale state from leaking into subsequent turns.
30
- */
31
5
  export declare function consumeCurrentTurnIsOwner(): boolean;
32
6
  //# sourceMappingURL=owner-session-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"owner-session-state.d.ts","sourceRoot":"","sources":["../src/owner-session-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAgBH,iDAAiD;AACjD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEtD;AAED,gDAAgD;AAChD,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,uEAAuE;AACvE,wBAAgB,eAAe,IAAI,IAAI,CAGtC;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAE1D;AAMD;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,OAAO,CAInD"}
1
+ {"version":3,"file":"owner-session-state.d.ts","sourceRoot":"","sources":["../src/owner-session-state.ts"],"names":[],"mappings":"AA+BA,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEtD;AAGD,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEvD;AAGD,wBAAgB,eAAe,IAAI,IAAI,CAGtC;AAMD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAE1D;AAUD,wBAAgB,yBAAyB,IAAI,OAAO,CAInD"}
@@ -1,55 +1,18 @@
1
- /**
2
- * Owner Identity State — tracks which addresses belong to the agent's owner.
3
- *
4
- * When the Connector detects that a Passport visitor is the agent's owner
5
- * (deterministic userId comparison, #836), it includes `is_owner: true` in
6
- * MESSAGE_RECEIVED metadata. This module maintains the Plugin-side state:
7
- *
8
- * - `ownerAddresses`: Set of routable addresses where the visitor is the owner.
9
- * Populated on first MESSAGE_RECEIVED with is_owner=true, cleared on disconnect.
10
- *
11
- * - `currentTurnIsOwner`: Per-turn flag set in the message_received handler
12
- * and read in before_prompt_build. Reset after each read to avoid stale state.
13
- *
14
- * Module-level singleton — shared between channel.ts (write) and plugin.ts (read).
15
- */
16
- // ---------------------------------------------------------------------------
17
- // State
18
- // ---------------------------------------------------------------------------
19
- /** Routable addresses where the visitor has been identified as the owner. */
20
1
  const ownerAddresses = new Set();
21
- /** Whether the current LLM turn was triggered by an owner. */
22
2
  let currentTurnIsOwner = false;
23
- // ---------------------------------------------------------------------------
24
- // Write API (called from channel.ts)
25
- // ---------------------------------------------------------------------------
26
- /** Mark an address as belonging to the owner. */
27
3
  export function markOwnerAddress(address) {
28
4
  ownerAddresses.add(address);
29
5
  }
30
- /** Check if an address belongs to the owner. */
31
6
  export function isOwnerAddress(address) {
32
7
  return ownerAddresses.has(address);
33
8
  }
34
- /** Clear all owner state (connection lost — all addresses invalid). */
35
9
  export function clearOwnerState() {
36
10
  ownerAddresses.clear();
37
11
  currentTurnIsOwner = false;
38
12
  }
39
- /**
40
- * Set the per-turn owner flag. Called in message_received before dispatch.
41
- * The flag is consumed (read + reset) by before_prompt_build.
42
- */
43
13
  export function setCurrentTurnIsOwner(value) {
44
14
  currentTurnIsOwner = value;
45
15
  }
46
- // ---------------------------------------------------------------------------
47
- // Read API (called from plugin.ts)
48
- // ---------------------------------------------------------------------------
49
- /**
50
- * Consume the per-turn owner flag. Returns the value and resets to false.
51
- * Consuming prevents stale state from leaking into subsequent turns.
52
- */
53
16
  export function consumeCurrentTurnIsOwner() {
54
17
  const value = currentTurnIsOwner;
55
18
  currentTurnIsOwner = false;