@masons/agent-network 0.4.7 → 0.4.8
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.map +1 -1
- package/dist/channel.js +19 -0
- package/dist/owner-session-state.d.ts +39 -0
- package/dist/owner-session-state.d.ts.map +1 -0
- package/dist/owner-session-state.js +66 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +41 -7
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/channel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAqB9D,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,oBAAoB,CAAC,CAAC;IAC9B,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAAC;IACvD,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC;IACpE,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;IACjE,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;CAC/D;AAED,UAAU,sBAAsB;IAC9B,EAAE,EAAE,OAAO,CAAC;CACb;AAED,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,sBAAsB;IAC9B,YAAY,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC9C,QAAQ,CAAC,CAAC,GAAG,EAAE,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;CACzE;AAED,UAAU,qBAAqB,CAAC,CAAC,GAAG,OAAO;IACzC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAsDD,UAAU,qBAAqB,CAAC,CAAC,GAAG,OAAO;IACzC,YAAY,CAAC,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/D,WAAW,CAAC,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAED,UAAU,yBAAyB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,YAAY,EAAE,mBAAmB,CAAC;IAClC,MAAM,EAAE,oBAAoB,CAAC,mBAAmB,CAAC,CAAC;IAClD,QAAQ,EAAE,sBAAsB,CAAC;IACjC,OAAO,EAAE,qBAAqB,CAAC,mBAAmB,CAAC,CAAC;CACrD;AAkED,eAAO,MAAM,mBAAmB,EAAE,yBAsYjC,CAAC"}
|
package/dist/channel.js
CHANGED
|
@@ -3,6 +3,7 @@ import createDebug from "debug";
|
|
|
3
3
|
import { clearConnectorClient, clearConversationManager, extractNetworkConfig, initConnectorClient, initConversationManager, initToolConfig, requirePluginRuntime, } from "./config.js";
|
|
4
4
|
import { ConnectorClient } from "./connector-client.js";
|
|
5
5
|
import { ConversationManager } from "./conversation-manager.js";
|
|
6
|
+
import { clearOwnerSessions, isOwnerSession, markOwnerSession, removeOwnerSession, setCurrentTurnIsOwner, } from "./owner-session-state.js";
|
|
6
7
|
import { checkForUpdate } from "./update-check.js";
|
|
7
8
|
const dbg = createDebug("agent-network:channel");
|
|
8
9
|
// --- Sender identity ---
|
|
@@ -144,6 +145,9 @@ export const agentNetworkChannel = {
|
|
|
144
145
|
// structured multi-step interactions, add a per-session dispatch queue.
|
|
145
146
|
client.on("message_received", async (event) => {
|
|
146
147
|
dbg("routing inbound message sessionId=%s contentLength=%d", event.sessionId, event.content.length);
|
|
148
|
+
// --- Owner turn detection (#836) ---
|
|
149
|
+
// Set BEFORE dispatch so before_prompt_build can read it.
|
|
150
|
+
setCurrentTurnIsOwner(isOwnerSession(event.sessionId));
|
|
147
151
|
// --- Runtime guard ---
|
|
148
152
|
let runtime;
|
|
149
153
|
try {
|
|
@@ -253,6 +257,13 @@ export const agentNetworkChannel = {
|
|
|
253
257
|
client.on("session_created", (event) => {
|
|
254
258
|
dbg("session created sessionId=%s direction=%s", event.sessionId, event.direction);
|
|
255
259
|
if (event.direction === "inbound") {
|
|
260
|
+
// --- Owner identity binding (#836) ---
|
|
261
|
+
// Connector sets `is_owner: true` when visitor_user_id === agent.userId.
|
|
262
|
+
// Track this session so message_received can set the per-turn flag.
|
|
263
|
+
if (event.metadata?.is_owner === true) {
|
|
264
|
+
markOwnerSession(event.sessionId);
|
|
265
|
+
dbg("owner session detected sessionId=%s", event.sessionId);
|
|
266
|
+
}
|
|
256
267
|
const from = event.metadata?.from;
|
|
257
268
|
const remoteAddress = typeof from === "string" && from.length > 0 ? from : null;
|
|
258
269
|
if (remoteAddress) {
|
|
@@ -281,6 +292,14 @@ export const agentNetworkChannel = {
|
|
|
281
292
|
// --- Session ended + disconnect ---
|
|
282
293
|
// SessionLifecycle handles session state transitions (session_ended, disconnected)
|
|
283
294
|
// via its own event subscriptions. No CM calls needed here.
|
|
295
|
+
// Owner session cleanup (#836): remove from ownerSessionIds on session_ended.
|
|
296
|
+
client.on("session_ended", (event) => {
|
|
297
|
+
removeOwnerSession(event.sessionId);
|
|
298
|
+
});
|
|
299
|
+
// On disconnect, all sessions are invalid — clear owner state.
|
|
300
|
+
client.on("disconnected", () => {
|
|
301
|
+
clearOwnerSessions();
|
|
302
|
+
});
|
|
284
303
|
// --- Error handling ---
|
|
285
304
|
// Must register before connect() — unhandled "error" events crash the process.
|
|
286
305
|
client.on("error", (err) => {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Owner Session State — tracks which MSTP sessions 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 sets `is_owner: true` in the
|
|
6
|
+
* SESSION_CREATED metadata. This module maintains the Plugin-side state:
|
|
7
|
+
*
|
|
8
|
+
* - `ownerSessionIds`: Set of session IDs where the visitor is the owner.
|
|
9
|
+
* Populated on session_created, cleaned up on session_ended / disconnected.
|
|
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
|
+
* Race condition note (from design review): if two messages arrive on
|
|
14
|
+
* different sessions concurrently, the flag may reflect the wrong session.
|
|
15
|
+
* Fail-safe: owner gets the routing warning (same as today's behavior).
|
|
16
|
+
* Acceptable for Phase 1 — OpenClaw processes turns sequentially per agent.
|
|
17
|
+
*
|
|
18
|
+
* Module-level singleton — shared between channel.ts (write) and plugin.ts (read).
|
|
19
|
+
* Same pattern as owner-notes.ts.
|
|
20
|
+
*/
|
|
21
|
+
/** Mark a session as belonging to the owner. */
|
|
22
|
+
export declare function markOwnerSession(sessionId: string): void;
|
|
23
|
+
/** Remove a session from owner tracking (session ended or disconnected). */
|
|
24
|
+
export declare function removeOwnerSession(sessionId: string): void;
|
|
25
|
+
/** Clear all owner sessions (connection lost — all sessions are invalid). */
|
|
26
|
+
export declare function clearOwnerSessions(): void;
|
|
27
|
+
/** Check if a session belongs to the owner. */
|
|
28
|
+
export declare function isOwnerSession(sessionId: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Set the per-turn owner flag. Called in message_received before dispatch.
|
|
31
|
+
* The flag is consumed (read + reset) by before_prompt_build.
|
|
32
|
+
*/
|
|
33
|
+
export declare function setCurrentTurnIsOwner(value: boolean): void;
|
|
34
|
+
/**
|
|
35
|
+
* Consume the per-turn owner flag. Returns the value and resets to false.
|
|
36
|
+
* Consuming prevents stale state from leaking into subsequent turns.
|
|
37
|
+
*/
|
|
38
|
+
export declare function consumeCurrentTurnIsOwner(): boolean;
|
|
39
|
+
//# sourceMappingURL=owner-session-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"owner-session-state.d.ts","sourceRoot":"","sources":["../src/owner-session-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAgBH,gDAAgD;AAChD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAExD;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE1D;AAED,6EAA6E;AAC7E,wBAAgB,kBAAkB,IAAI,IAAI,CAGzC;AAED,+CAA+C;AAC/C,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAE1D;AAMD;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,OAAO,CAInD"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Owner Session State — tracks which MSTP sessions 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 sets `is_owner: true` in the
|
|
6
|
+
* SESSION_CREATED metadata. This module maintains the Plugin-side state:
|
|
7
|
+
*
|
|
8
|
+
* - `ownerSessionIds`: Set of session IDs where the visitor is the owner.
|
|
9
|
+
* Populated on session_created, cleaned up on session_ended / disconnected.
|
|
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
|
+
* Race condition note (from design review): if two messages arrive on
|
|
14
|
+
* different sessions concurrently, the flag may reflect the wrong session.
|
|
15
|
+
* Fail-safe: owner gets the routing warning (same as today's behavior).
|
|
16
|
+
* Acceptable for Phase 1 — OpenClaw processes turns sequentially per agent.
|
|
17
|
+
*
|
|
18
|
+
* Module-level singleton — shared between channel.ts (write) and plugin.ts (read).
|
|
19
|
+
* Same pattern as owner-notes.ts.
|
|
20
|
+
*/
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// State
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
/** Session IDs where the visitor has been identified as the agent's owner. */
|
|
25
|
+
const ownerSessionIds = new Set();
|
|
26
|
+
/** Whether the current LLM turn was triggered by an owner session. */
|
|
27
|
+
let currentTurnIsOwner = false;
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Write API (called from channel.ts)
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
/** Mark a session as belonging to the owner. */
|
|
32
|
+
export function markOwnerSession(sessionId) {
|
|
33
|
+
ownerSessionIds.add(sessionId);
|
|
34
|
+
}
|
|
35
|
+
/** Remove a session from owner tracking (session ended or disconnected). */
|
|
36
|
+
export function removeOwnerSession(sessionId) {
|
|
37
|
+
ownerSessionIds.delete(sessionId);
|
|
38
|
+
}
|
|
39
|
+
/** Clear all owner sessions (connection lost — all sessions are invalid). */
|
|
40
|
+
export function clearOwnerSessions() {
|
|
41
|
+
ownerSessionIds.clear();
|
|
42
|
+
currentTurnIsOwner = false;
|
|
43
|
+
}
|
|
44
|
+
/** Check if a session belongs to the owner. */
|
|
45
|
+
export function isOwnerSession(sessionId) {
|
|
46
|
+
return ownerSessionIds.has(sessionId);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Set the per-turn owner flag. Called in message_received before dispatch.
|
|
50
|
+
* The flag is consumed (read + reset) by before_prompt_build.
|
|
51
|
+
*/
|
|
52
|
+
export function setCurrentTurnIsOwner(value) {
|
|
53
|
+
currentTurnIsOwner = value;
|
|
54
|
+
}
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// Read API (called from plugin.ts)
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
/**
|
|
59
|
+
* Consume the per-turn owner flag. Returns the value and resets to false.
|
|
60
|
+
* Consuming prevents stale state from leaking into subsequent turns.
|
|
61
|
+
*/
|
|
62
|
+
export function consumeCurrentTurnIsOwner() {
|
|
63
|
+
const value = currentTurnIsOwner;
|
|
64
|
+
currentTurnIsOwner = false;
|
|
65
|
+
return value;
|
|
66
|
+
}
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAmCA,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;CACnE;AAED,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;kBA4BI,iBAAiB;CAqPhC,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/plugin.js
CHANGED
|
@@ -5,6 +5,7 @@ import { agentNetworkChannel } from "./channel.js";
|
|
|
5
5
|
import { configureInteractive } from "./cli-setup.js";
|
|
6
6
|
import { detectPendingState, getStateCacheGeneration, initPluginRuntime, } from "./config.js";
|
|
7
7
|
import { ownerNotesQueue } from "./owner-notes.js";
|
|
8
|
+
import { consumeCurrentTurnIsOwner } from "./owner-session-state.js";
|
|
8
9
|
import { registerTools } from "./tools.js";
|
|
9
10
|
import { getUpdateInfo } from "./update-check.js";
|
|
10
11
|
import { PLUGIN_VERSION } from "./version.js";
|
|
@@ -173,13 +174,46 @@ const plugin = {
|
|
|
173
174
|
!state.needsProfile &&
|
|
174
175
|
!state.pendingTarget) {
|
|
175
176
|
if (channelId === "agent-network") {
|
|
176
|
-
//
|
|
177
|
-
//
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
177
|
+
// --- Owner identity binding (#836) ---
|
|
178
|
+
// Consume the per-turn owner flag set by channel.ts message_received.
|
|
179
|
+
// Must consume on every agent-network turn to prevent stale state.
|
|
180
|
+
const turnIsOwner = consumeCurrentTurnIsOwner();
|
|
181
|
+
if (turnIsOwner) {
|
|
182
|
+
// Owner visiting via Passport — no routing warning needed.
|
|
183
|
+
// The LLM's text reply goes to the owner (the visitor IS the owner).
|
|
184
|
+
// Drain pending notes: owner is here, deliver them directly.
|
|
185
|
+
const notes = ownerNotesQueue.drain();
|
|
186
|
+
const notesBlock = notes.length > 0
|
|
187
|
+
? "\n\nPending updates from the agent network:\n" +
|
|
188
|
+
notes
|
|
189
|
+
.map((n) => {
|
|
190
|
+
const fromStr = n.from ? `@${n.from}` : "agent";
|
|
191
|
+
const timeStr = formatTimeAgo(n.timestamp);
|
|
192
|
+
const preview = n.content.length > 100
|
|
193
|
+
? `${n.content.slice(0, 100)}...`
|
|
194
|
+
: n.content;
|
|
195
|
+
return `• ${fromStr} (${timeStr}): "${preview}"`;
|
|
196
|
+
})
|
|
197
|
+
.join("\n")
|
|
198
|
+
: "";
|
|
199
|
+
dynamicContext =
|
|
200
|
+
"[Agent Network — Owner via Passport] Your owner (Principal) is talking to you " +
|
|
201
|
+
"via Passport (your public web chat page where visitors can reach you). " +
|
|
202
|
+
"This IS your owner — respond naturally, no need to ask who they are. " +
|
|
203
|
+
"Your text reply goes directly to your owner. " +
|
|
204
|
+
"You can share information freely — no information boundary applies. " +
|
|
205
|
+
"Do NOT use masons_note_for_owner — your owner is right here." +
|
|
206
|
+
notesBlock;
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
// Turn triggered by a remote agent/stranger — warn about routing.
|
|
210
|
+
// The LLM's text reply will go to that sender via deliver callback.
|
|
211
|
+
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
|
+
}
|
|
183
217
|
}
|
|
184
218
|
else {
|
|
185
219
|
// Owner turn (or other channel) — drain pending notes if any.
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Plugin version — must match package.json. Validated by prepublishOnly. */
|
|
2
|
-
export const PLUGIN_VERSION = "0.4.
|
|
2
|
+
export const PLUGIN_VERSION = "0.4.8";
|
package/package.json
CHANGED