@masons/agent-network 0.6.20 → 0.6.21
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 +54 -44
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +6 -0
- package/dist/connector-client.d.ts +35 -4
- package/dist/connector-client.d.ts.map +1 -1
- package/dist/connector-client.js +126 -19
- package/dist/conversation-manager-context.d.ts +4 -0
- package/dist/conversation-manager-context.d.ts.map +1 -0
- package/dist/conversation-manager-context.js +8 -0
- package/dist/conversation-manager.d.ts +29 -4
- package/dist/conversation-manager.d.ts.map +1 -1
- package/dist/conversation-manager.js +163 -14
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/platform-client.d.ts +1 -0
- package/dist/platform-client.d.ts.map +1 -1
- package/dist/platform-client.js +12 -0
- package/dist/plugin.d.ts +2 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +49 -30
- package/dist/sent-message-buffer.d.ts +2 -3
- package/dist/sent-message-buffer.d.ts.map +1 -1
- package/dist/sent-message-buffer.js +8 -11
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +101 -7
- package/dist/turn-context.d.ts +0 -4
- package/dist/turn-context.d.ts.map +1 -1
- package/dist/turn-context.js +0 -18
- package/dist/types.d.ts +10 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/ws-heartbeat.d.ts +23 -0
- package/dist/ws-heartbeat.d.ts.map +1 -0
- package/dist/ws-heartbeat.js +63 -0
- package/openclaw.plugin.json +2 -1
- package/package.json +1 -1
- package/skills/agent-network/SKILL.md +9 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
const conversationManagerContext = new AsyncLocalStorage();
|
|
3
|
+
export function runWithConversationManagerContext(manager, callback) {
|
|
4
|
+
return conversationManagerContext.run(manager, callback);
|
|
5
|
+
}
|
|
6
|
+
export function getInvocationConversationManager() {
|
|
7
|
+
return conversationManagerContext.getStore() ?? null;
|
|
8
|
+
}
|
|
@@ -1,9 +1,25 @@
|
|
|
1
|
-
import { type ConnectorClient } from "./connector-client.js";
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { type ConnectorClient, type SendOutcomeUnknownReason } from "./connector-client.js";
|
|
2
|
+
import { type SentMessage } from "./sent-message-buffer.js";
|
|
3
|
+
import type { SendAckEvent } from "./types.js";
|
|
4
|
+
export type SendResult = {
|
|
5
|
+
status: "sent";
|
|
6
|
+
messageId: string;
|
|
7
|
+
acknowledgementStatus: string;
|
|
8
|
+
messageRef?: string;
|
|
9
|
+
addressedTarget?: NonNullable<SendAckEvent["addressedTarget"]>;
|
|
10
|
+
} | {
|
|
11
|
+
status: "unknown";
|
|
12
|
+
messageId: string;
|
|
13
|
+
attempts: 1;
|
|
14
|
+
retryable: false;
|
|
15
|
+
reason: SendOutcomeUnknownReason;
|
|
16
|
+
error: string;
|
|
17
|
+
errorCode: "SEND_OUTCOME_UNKNOWN";
|
|
18
|
+
} | {
|
|
19
|
+
status: "failed";
|
|
4
20
|
error?: string;
|
|
5
21
|
errorCode?: string;
|
|
6
|
-
}
|
|
22
|
+
};
|
|
7
23
|
export interface ConversationEntry {
|
|
8
24
|
contact: string;
|
|
9
25
|
address: string;
|
|
@@ -28,11 +44,16 @@ export interface InboundEnvelope {
|
|
|
28
44
|
export declare const REPLY_CORRELATION_MAX_AGE_MS: number;
|
|
29
45
|
export declare class ConversationManager {
|
|
30
46
|
private readonly client;
|
|
47
|
+
private readonly sentMessageBuffer;
|
|
31
48
|
private readonly conversations;
|
|
49
|
+
private readonly conversationAliases;
|
|
32
50
|
private readonly pendingOutreach;
|
|
33
51
|
constructor(client: ConnectorClient);
|
|
52
|
+
recordOutboundContext(peerAddress: string, content: string): void;
|
|
53
|
+
getRecentOutboundContext(peerAddress: string): SentMessage[];
|
|
34
54
|
send(contact: string, content: string, metadata?: Record<string, unknown>): Promise<SendResult>;
|
|
35
55
|
registerInbound(contact: string, address: string): void;
|
|
56
|
+
refreshInboundPortrayal(contact: string, address: string): boolean;
|
|
36
57
|
recordInboundEnvelope(address: string, envelope: Omit<InboundEnvelope, "receivedAt">): void;
|
|
37
58
|
getContactByAddress(address: string): string | undefined;
|
|
38
59
|
listConversations(): ConversationSummary[];
|
|
@@ -42,6 +63,10 @@ export declare class ConversationManager {
|
|
|
42
63
|
resolveAddress(contact: string): string;
|
|
43
64
|
private resolveContactForSend;
|
|
44
65
|
extractHandle(address: string): string;
|
|
66
|
+
private resolveConversationAlias;
|
|
67
|
+
private recordConversationAlias;
|
|
68
|
+
private deleteConversationAliases;
|
|
69
|
+
private fileResolvedConversation;
|
|
45
70
|
private ensureConversationEntry;
|
|
46
71
|
_resetForTesting(): void;
|
|
47
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-manager.d.ts","sourceRoot":"","sources":["../src/conversation-manager.ts"],"names":[],"mappings":"AAiBA,OAAO,
|
|
1
|
+
{"version":3,"file":"conversation-manager.d.ts","sourceRoot":"","sources":["../src/conversation-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import createDebug from "debug";
|
|
2
|
-
import { ConnectorError } from "./connector-client.js";
|
|
2
|
+
import { ConnectorError, SendOutcomeUnknownError, } from "./connector-client.js";
|
|
3
3
|
import { extractHandleFromAddress } from "./handle-utils.js";
|
|
4
|
+
import { SentMessageBuffer } from "./sent-message-buffer.js";
|
|
4
5
|
import { createReplyTraceMetadata, ensureTraceMetadata, } from "./trace-metadata.js";
|
|
5
6
|
const dbg = createDebug("agent-network:conversation-manager");
|
|
6
7
|
export const REPLY_CORRELATION_MAX_AGE_MS = 10 * 60_000;
|
|
@@ -19,17 +20,68 @@ function normalizeHandleContact(contact) {
|
|
|
19
20
|
return contact.startsWith("@") ? contact.slice(1) : contact;
|
|
20
21
|
}
|
|
21
22
|
function isRoutableAddress(value) {
|
|
22
|
-
return (value.startsWith("
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
return /^mstps?:\/\//i.test(value) || value.startsWith("passport:");
|
|
24
|
+
}
|
|
25
|
+
function isAddressedTargetAddress(value) {
|
|
26
|
+
for (let index = 0; index < value.length; index++) {
|
|
27
|
+
const codeUnit = value.charCodeAt(index);
|
|
28
|
+
if (codeUnit <= 0x1f || codeUnit === 0x7f)
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
if (!/^mstps?:\/\//i.test(value)) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const parsed = new URL(value);
|
|
36
|
+
return ((parsed.protocol === "mstp:" || parsed.protocol === "mstps:") &&
|
|
37
|
+
parsed.hostname.length > 0);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function isCanonicalResolvedNodeAddress(value) {
|
|
44
|
+
return /^mstps?:\/\/[a-z0-9.-]+(?::[0-9]+)?\/[a-z][a-z0-9_-]{2,14}$/.test(value);
|
|
45
|
+
}
|
|
46
|
+
function normalizedAddressedTarget(value) {
|
|
47
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
const candidate = value;
|
|
51
|
+
if (typeof candidate.address !== "string" ||
|
|
52
|
+
candidate.address.length === 0 ||
|
|
53
|
+
(candidate.basis !== "resolved" && candidate.basis !== "forwarded")) {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
const validAddress = candidate.basis === "resolved"
|
|
57
|
+
? isCanonicalResolvedNodeAddress(candidate.address)
|
|
58
|
+
: isAddressedTargetAddress(candidate.address);
|
|
59
|
+
if (!validAddress) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
address: candidate.address,
|
|
64
|
+
basis: candidate.basis,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function normalizedMessageRef(value) {
|
|
68
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
25
69
|
}
|
|
26
70
|
export class ConversationManager {
|
|
27
71
|
client;
|
|
72
|
+
sentMessageBuffer = new SentMessageBuffer();
|
|
28
73
|
conversations = new Map();
|
|
74
|
+
conversationAliases = new Map();
|
|
29
75
|
pendingOutreach = new Set();
|
|
30
76
|
constructor(client) {
|
|
31
77
|
this.client = client;
|
|
32
78
|
}
|
|
79
|
+
recordOutboundContext(peerAddress, content) {
|
|
80
|
+
this.sentMessageBuffer.record(peerAddress, content);
|
|
81
|
+
}
|
|
82
|
+
getRecentOutboundContext(peerAddress) {
|
|
83
|
+
return this.sentMessageBuffer.getRecent(peerAddress);
|
|
84
|
+
}
|
|
33
85
|
async send(contact, content, metadata) {
|
|
34
86
|
const resolution = this.resolveContactForSend(contact);
|
|
35
87
|
if (resolution.ambiguous) {
|
|
@@ -74,16 +126,45 @@ export class ConversationManager {
|
|
|
74
126
|
}
|
|
75
127
|
try {
|
|
76
128
|
const ack = await this.client.send(address, content, "text", wireMetadata);
|
|
77
|
-
|
|
129
|
+
const addressedTarget = normalizedAddressedTarget(ack.addressedTarget);
|
|
130
|
+
const messageRef = normalizedMessageRef(ack.messageRef);
|
|
131
|
+
const resolvedAddress = addressedTarget?.basis === "resolved"
|
|
132
|
+
? addressedTarget.address
|
|
133
|
+
: undefined;
|
|
134
|
+
if (resolvedAddress !== undefined) {
|
|
135
|
+
if (!isRoutableAddress(address)) {
|
|
136
|
+
this.pendingOutreach.delete(normalizeHandleContact(address).toLowerCase());
|
|
137
|
+
}
|
|
138
|
+
this.fileResolvedConversation(address, resolvedAddress);
|
|
139
|
+
}
|
|
140
|
+
else if (isRoutableAddress(address)) {
|
|
78
141
|
this.ensureConversationEntry(this.extractHandle(address), address, "local");
|
|
79
142
|
}
|
|
80
143
|
else {
|
|
81
144
|
this.pendingOutreach.add(address.toLowerCase());
|
|
82
145
|
}
|
|
83
146
|
dbg("send contact=%s address=%s status=%s traceId=%s spanName=send", contact, address, ack.status, sendTraceId);
|
|
84
|
-
return {
|
|
147
|
+
return {
|
|
148
|
+
status: "sent",
|
|
149
|
+
messageId: ack.messageId,
|
|
150
|
+
acknowledgementStatus: ack.status,
|
|
151
|
+
...(messageRef !== undefined && { messageRef }),
|
|
152
|
+
...(addressedTarget !== undefined && { addressedTarget }),
|
|
153
|
+
};
|
|
85
154
|
}
|
|
86
155
|
catch (err) {
|
|
156
|
+
if (err instanceof SendOutcomeUnknownError) {
|
|
157
|
+
dbg("send outcome unknown contact=%s messageId=%s reason=%s", contact, err.messageId, err.reason);
|
|
158
|
+
return {
|
|
159
|
+
status: "unknown",
|
|
160
|
+
messageId: err.messageId,
|
|
161
|
+
attempts: err.attempts,
|
|
162
|
+
retryable: err.retryable,
|
|
163
|
+
reason: err.reason,
|
|
164
|
+
error: err.message,
|
|
165
|
+
errorCode: err.code,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
87
168
|
if (err instanceof ConnectorError) {
|
|
88
169
|
const message = formatErrorMessage(err.code, err.to ?? contact);
|
|
89
170
|
dbg("send failed contact=%s code=%s message=%s", contact, err.code, message);
|
|
@@ -98,8 +179,16 @@ export class ConversationManager {
|
|
|
98
179
|
this.ensureConversationEntry(contact, address, "remote");
|
|
99
180
|
dbg("registerInbound contact=%s address=%s", contact, address);
|
|
100
181
|
}
|
|
182
|
+
refreshInboundPortrayal(contact, address) {
|
|
183
|
+
const entry = this.conversations.get(this.resolveConversationAlias(address));
|
|
184
|
+
if (!entry)
|
|
185
|
+
return false;
|
|
186
|
+
entry.contact = contact;
|
|
187
|
+
dbg("refreshInboundPortrayal contact=%s address=%s", contact, address);
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
101
190
|
recordInboundEnvelope(address, envelope) {
|
|
102
|
-
const entry = this.conversations.get(address);
|
|
191
|
+
const entry = this.conversations.get(this.resolveConversationAlias(address));
|
|
103
192
|
if (!entry) {
|
|
104
193
|
dbg("recordInboundEnvelope no entry, skipped address=%s", address);
|
|
105
194
|
return;
|
|
@@ -108,7 +197,7 @@ export class ConversationManager {
|
|
|
108
197
|
dbg("recordInboundEnvelope address=%s messageId=%s correlationId=%s", address, envelope.messageId ?? "(absent)", envelope.correlationId ?? "(absent)");
|
|
109
198
|
}
|
|
110
199
|
getContactByAddress(address) {
|
|
111
|
-
const entry = this.conversations.get(address);
|
|
200
|
+
const entry = this.conversations.get(this.resolveConversationAlias(address));
|
|
112
201
|
if (entry)
|
|
113
202
|
return entry.contact;
|
|
114
203
|
for (const [, e] of this.conversations) {
|
|
@@ -155,6 +244,7 @@ export class ConversationManager {
|
|
|
155
244
|
for (const [address, entry] of this.conversations) {
|
|
156
245
|
if (entry.ended) {
|
|
157
246
|
this.conversations.delete(address);
|
|
247
|
+
this.deleteConversationAliases(address);
|
|
158
248
|
count++;
|
|
159
249
|
}
|
|
160
250
|
}
|
|
@@ -167,7 +257,10 @@ export class ConversationManager {
|
|
|
167
257
|
}
|
|
168
258
|
resolveContactForSend(contact) {
|
|
169
259
|
if (isRoutableAddress(contact)) {
|
|
170
|
-
return {
|
|
260
|
+
return {
|
|
261
|
+
address: this.resolveConversationAlias(contact),
|
|
262
|
+
ambiguous: false,
|
|
263
|
+
};
|
|
171
264
|
}
|
|
172
265
|
const normalizedContact = normalizeHandleContact(contact);
|
|
173
266
|
if (this.conversations.has(normalizedContact)) {
|
|
@@ -194,22 +287,77 @@ export class ConversationManager {
|
|
|
194
287
|
extractHandle(address) {
|
|
195
288
|
return extractHandleFromAddress(address);
|
|
196
289
|
}
|
|
290
|
+
resolveConversationAlias(address) {
|
|
291
|
+
return this.conversationAliases.get(address) ?? address;
|
|
292
|
+
}
|
|
293
|
+
recordConversationAlias(aliasAddress, canonicalAddress) {
|
|
294
|
+
if (aliasAddress === canonicalAddress)
|
|
295
|
+
return;
|
|
296
|
+
this.conversationAliases.delete(canonicalAddress);
|
|
297
|
+
for (const [alias, target] of this.conversationAliases) {
|
|
298
|
+
if (target === aliasAddress) {
|
|
299
|
+
this.conversationAliases.set(alias, canonicalAddress);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
this.conversationAliases.set(aliasAddress, canonicalAddress);
|
|
303
|
+
}
|
|
304
|
+
deleteConversationAliases(canonicalAddress) {
|
|
305
|
+
for (const [alias, target] of this.conversationAliases) {
|
|
306
|
+
if (target === canonicalAddress)
|
|
307
|
+
this.conversationAliases.delete(alias);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
fileResolvedConversation(sentAddress, resolvedAddress) {
|
|
311
|
+
const prior = sentAddress !== resolvedAddress && isRoutableAddress(sentAddress)
|
|
312
|
+
? this.conversations.get(sentAddress)
|
|
313
|
+
: undefined;
|
|
314
|
+
const canonical = this.conversations.get(resolvedAddress);
|
|
315
|
+
if (prior)
|
|
316
|
+
this.conversations.delete(sentAddress);
|
|
317
|
+
if (sentAddress !== resolvedAddress && isRoutableAddress(sentAddress)) {
|
|
318
|
+
this.recordConversationAlias(sentAddress, resolvedAddress);
|
|
319
|
+
}
|
|
320
|
+
if (!canonical && prior) {
|
|
321
|
+
this.conversations.set(resolvedAddress, {
|
|
322
|
+
...prior,
|
|
323
|
+
address: resolvedAddress,
|
|
324
|
+
lastMessageAt: Date.now(),
|
|
325
|
+
ended: false,
|
|
326
|
+
});
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
if (canonical) {
|
|
330
|
+
canonical.lastMessageAt = Date.now();
|
|
331
|
+
canonical.ended = false;
|
|
332
|
+
if (prior?.initiatedBy === "local")
|
|
333
|
+
canonical.initiatedBy = "local";
|
|
334
|
+
if (prior?.inboundEnvelope &&
|
|
335
|
+
(!canonical.inboundEnvelope ||
|
|
336
|
+
prior.inboundEnvelope.receivedAt >
|
|
337
|
+
canonical.inboundEnvelope.receivedAt)) {
|
|
338
|
+
canonical.inboundEnvelope = prior.inboundEnvelope;
|
|
339
|
+
}
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
this.ensureConversationEntry(this.extractHandle(resolvedAddress), resolvedAddress, "local");
|
|
343
|
+
}
|
|
197
344
|
ensureConversationEntry(contact, address, initiatedBy) {
|
|
198
|
-
|
|
199
|
-
|
|
345
|
+
const canonicalAddress = this.resolveConversationAlias(address);
|
|
346
|
+
if (!this.conversations.has(canonicalAddress)) {
|
|
347
|
+
const outreachKey = extractHandleFromAddress(canonicalAddress).toLowerCase();
|
|
200
348
|
let origin = initiatedBy;
|
|
201
349
|
if (origin === "remote" && this.pendingOutreach.delete(outreachKey)) {
|
|
202
350
|
origin = "local";
|
|
203
351
|
}
|
|
204
|
-
this.conversations.set(
|
|
352
|
+
this.conversations.set(canonicalAddress, {
|
|
205
353
|
contact,
|
|
206
|
-
address,
|
|
354
|
+
address: canonicalAddress,
|
|
207
355
|
lastMessageAt: Date.now(),
|
|
208
356
|
initiatedBy: origin,
|
|
209
357
|
});
|
|
210
358
|
}
|
|
211
359
|
else {
|
|
212
|
-
const entry = this.conversations.get(
|
|
360
|
+
const entry = this.conversations.get(canonicalAddress);
|
|
213
361
|
if (entry) {
|
|
214
362
|
entry.lastMessageAt = Date.now();
|
|
215
363
|
entry.ended = false;
|
|
@@ -218,5 +366,6 @@ export class ConversationManager {
|
|
|
218
366
|
}
|
|
219
367
|
_resetForTesting() {
|
|
220
368
|
this.conversations.clear();
|
|
369
|
+
this.conversationAliases.clear();
|
|
221
370
|
}
|
|
222
371
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { AUTHORIZED_TOKEN_TTL_MS, SETUP_CODE_CHARSET, SETUP_CODE_LENGTH, SETUP_CODE_TTL_MS, } from "./constants.js";
|
|
2
2
|
export type { AgentNetworkAccount } from "./config-schema.js";
|
|
3
|
-
export type { AddressedMessageEvent, DeliveryPendingEvent, DeliverySkipEvent, DeliveryStatusEvent, RegisterAckEvent, SendAckEvent, StructuredErrorEvent, } from "./types.js";
|
|
3
|
+
export type { AddressedMessageEvent, DeliveryPendingEvent, DeliverySkipEvent, DeliveryStatusEvent, ObservedSendAckEvent, RegisterAckEvent, SendAckEvent, StructuredErrorEvent, } from "./types.js";
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAIxB,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,YAAY,EACZ,oBAAoB,GACrB,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAIxB,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,EACZ,oBAAoB,GACrB,MAAM,YAAY,CAAC"}
|
|
@@ -87,4 +87,5 @@ export declare function acceptRequest(cfg: PlatformClientConfig, runtimeKey: str
|
|
|
87
87
|
export declare function declineRequest(cfg: PlatformClientConfig, runtimeKey: string, requestId: string): Promise<DeclineRequestResponse>;
|
|
88
88
|
export declare function updateProfile(cfg: PlatformClientConfig, runtimeKey: string, params: UpdateProfileParams): Promise<UpdateProfileResponse>;
|
|
89
89
|
export declare function listConnections(cfg: PlatformClientConfig, runtimeKey: string): Promise<ListConnectionsResponse>;
|
|
90
|
+
export declare function getIdentity(cfg: PlatformClientConfig, runtimeKey: string): Promise<ConnectionNodeRef | null>;
|
|
90
91
|
//# sourceMappingURL=platform-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-client.d.ts","sourceRoot":"","sources":["../src/platform-client.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AASxD,eAAO,MAAM,qBAAqB,iDACc,CAAC;AAEjD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,qBAAa,gBAAiB,SAAQ,KAAK;aAEvB,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,MAAM;gBADZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EAC5B,OAAO,EAAE,MAAM;CAKlB;AAiBD,qBAAa,oBAAqB,SAAQ,KAAK;aAE3B,IAAI,EAAE,SAAS,GAAG,SAAS;aAE3B,MAAM,EAAE,MAAM;gBAFd,IAAI,EAAE,SAAS,GAAG,SAAS,EAE3B,MAAM,EAAE,MAAM;CAKjC;AAMD,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;
|
|
1
|
+
{"version":3,"file":"platform-client.d.ts","sourceRoot":"","sources":["../src/platform-client.ts"],"names":[],"mappings":"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"}
|
package/dist/platform-client.js
CHANGED
|
@@ -144,3 +144,15 @@ export async function listConnections(cfg, runtimeKey) {
|
|
|
144
144
|
return handleError(res);
|
|
145
145
|
return (await res.json());
|
|
146
146
|
}
|
|
147
|
+
export async function getIdentity(cfg, runtimeKey) {
|
|
148
|
+
const res = await apiFetch(`${baseUrl(cfg)}/me/identity`, {
|
|
149
|
+
headers: { Authorization: `Bearer ${runtimeKey}` },
|
|
150
|
+
});
|
|
151
|
+
if (!res.ok)
|
|
152
|
+
return handleError(res);
|
|
153
|
+
const body = (await res.json().catch(() => null));
|
|
154
|
+
if (!body || body.node === undefined) {
|
|
155
|
+
throw new PlatformApiError(res.status, "malformed_response", "identity response carried no `node` field");
|
|
156
|
+
}
|
|
157
|
+
return body.node;
|
|
158
|
+
}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { ConversationManager } from "./conversation-manager.js";
|
|
1
2
|
import { evaluateServicesRetainedToolPolicy } from "./services-retained-tool-policy.js";
|
|
2
|
-
export declare function buildInteractionContext(
|
|
3
|
+
export declare function buildInteractionContext(messageProvider: string | undefined, turnSenderAddress: string | null, conversationManager?: ConversationManager | null): string | undefined;
|
|
3
4
|
interface OpenClawPluginApi {
|
|
4
5
|
runtime: unknown;
|
|
5
6
|
registerChannel(opts: {
|
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":"AAcA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAUrE,OAAO,EACL,kCAAkC,EAEnC,MAAM,oCAAoC,CAAC;AA8D5C,wBAAgB,uBAAuB,CACrC,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,iBAAiB,EAAE,MAAM,GAAG,IAAI,EAChC,mBAAmB,GAAE,mBAAmB,GAAG,IAA+B,GACzE,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,yBAAyB,CAAC,MAAM,EAAE;QAChC,EAAE,EAAE,MAAM,CAAC;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,OAAO,kCAAkC,CAAC;KACrD,GAAG,IAAI,CAAC;IACT,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;CACnE;AAqCD,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAaI,iBAAiB;CA8ZhC,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/plugin.js
CHANGED
|
@@ -2,14 +2,14 @@ import pluginManifest from "../openclaw.plugin.json" with { type: "json" };
|
|
|
2
2
|
import { agentNetworkChannel, consumeIdentityLinkingNudge } from "./channel.js";
|
|
3
3
|
import { login } from "./cli-setup.js";
|
|
4
4
|
import { detectPendingState, getConversationManager, getDmScope, getStateCacheGeneration, initPluginRuntime, } from "./config.js";
|
|
5
|
+
import { getInvocationConversationManager } from "./conversation-manager-context.js";
|
|
5
6
|
import { getAgentIdentity } from "./environment-context.js";
|
|
6
7
|
import { ownerNotesQueue } from "./owner-notes.js";
|
|
7
8
|
import { consumeCurrentTurnIsOwner, consumeCurrentTurnOwnerSignal, } from "./owner-session-state.js";
|
|
8
|
-
import { sentMessageBuffer } from "./sent-message-buffer.js";
|
|
9
9
|
import { isServicesRetainedReplyContext } from "./services-retained-reply-context.js";
|
|
10
10
|
import { evaluateServicesRetainedToolPolicy, SERVICES_RETAINED_TOOL_POLICY_ID, } from "./services-retained-tool-policy.js";
|
|
11
11
|
import { registerTools } from "./tools.js";
|
|
12
|
-
import {
|
|
12
|
+
import { setCurrentTurnChannelId, setCurrentTurnIsOwnerForTools, setCurrentTurnOwnerSignalForTools, } from "./turn-context.js";
|
|
13
13
|
import { getUpdateInfo } from "./update-check.js";
|
|
14
14
|
import { PLUGIN_VERSION } from "./version.js";
|
|
15
15
|
function formatTimeAgo(timestamp) {
|
|
@@ -40,8 +40,8 @@ function drainAndFormatNotes(reportInstruction) {
|
|
|
40
40
|
reportInstruction);
|
|
41
41
|
}
|
|
42
42
|
const MAX_INTERACTIONS = 5;
|
|
43
|
-
export function buildInteractionContext(
|
|
44
|
-
const cm =
|
|
43
|
+
export function buildInteractionContext(messageProvider, turnSenderAddress, conversationManager = getConversationManager()) {
|
|
44
|
+
const cm = conversationManager;
|
|
45
45
|
if (!cm)
|
|
46
46
|
return undefined;
|
|
47
47
|
const conversations = cm.listConversations();
|
|
@@ -60,22 +60,18 @@ export function buildInteractionContext(channelId, turnSender, turnSenderAddress
|
|
|
60
60
|
const when = formatTimeAgo(c.lastMessageAt);
|
|
61
61
|
return `• ${who} — ${initiated} — last activity ${when}`;
|
|
62
62
|
});
|
|
63
|
-
const isNetworkTurn =
|
|
64
|
-
if (isNetworkTurn &&
|
|
65
|
-
const senderConvo = turnSenderAddress
|
|
66
|
-
? conversations.find((c) => c.address === turnSenderAddress)
|
|
67
|
-
: undefined;
|
|
63
|
+
const isNetworkTurn = messageProvider === "agent-network";
|
|
64
|
+
if (isNetworkTurn && turnSenderAddress) {
|
|
65
|
+
const senderConvo = conversations.find((c) => c.address === turnSenderAddress);
|
|
68
66
|
const initiated = senderConvo?.initiatedBy === "local"
|
|
69
67
|
? "You initiated this interaction."
|
|
70
68
|
: "They initiated this interaction.";
|
|
71
|
-
const from =
|
|
72
|
-
? `${
|
|
73
|
-
:
|
|
69
|
+
const from = senderConvo && senderConvo.contact !== turnSenderAddress
|
|
70
|
+
? `${senderConvo.contact} (${turnSenderAddress})`
|
|
71
|
+
: turnSenderAddress;
|
|
74
72
|
return (`${header}\n${lines.join("\n")}\n` +
|
|
75
73
|
`[This turn] From ${from}. ${initiated}\n` +
|
|
76
|
-
|
|
77
|
-
? "Your text reply uses the Services-retained reply authority for this message. "
|
|
78
|
-
: "Your text reply goes to this sender. ") +
|
|
74
|
+
"Your text reply goes to this sender. " +
|
|
79
75
|
"To report to your owner: masons_note_for_owner.");
|
|
80
76
|
}
|
|
81
77
|
if (isNetworkTurn) {
|
|
@@ -88,6 +84,24 @@ export function buildInteractionContext(channelId, turnSender, turnSenderAddress
|
|
|
88
84
|
: "[Active interactions on the network]";
|
|
89
85
|
return `${ownerHeader}\n${lines.join("\n")}`;
|
|
90
86
|
}
|
|
87
|
+
function resolveHookProvider(ctx) {
|
|
88
|
+
return ctx?.messageProvider ?? ctx?.channel;
|
|
89
|
+
}
|
|
90
|
+
function resolveHookSender(ctx, servicesRetained) {
|
|
91
|
+
if (servicesRetained || resolveHookProvider(ctx) !== "agent-network") {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
const senderId = ctx?.senderId;
|
|
95
|
+
return typeof senderId === "string" && senderId.length > 0 ? senderId : null;
|
|
96
|
+
}
|
|
97
|
+
function renderPeer(address, conversationManager) {
|
|
98
|
+
const conversation = conversationManager
|
|
99
|
+
.listConversations()
|
|
100
|
+
.find((entry) => entry.address === address);
|
|
101
|
+
return conversation && conversation.contact !== address
|
|
102
|
+
? `${conversation.contact} (${address})`
|
|
103
|
+
: address;
|
|
104
|
+
}
|
|
91
105
|
const plugin = {
|
|
92
106
|
id: "agent-network",
|
|
93
107
|
version: PLUGIN_VERSION,
|
|
@@ -130,7 +144,8 @@ const plugin = {
|
|
|
130
144
|
"masons_note_for_owner(content, from?) — save a note for your owner's next turn. " +
|
|
131
145
|
"Other network tools: masons_list_requests, masons_send_connection_request, " +
|
|
132
146
|
"masons_accept_request, masons_decline_request, masons_list_connections, " +
|
|
133
|
-
"masons_end_conversation (rare one-shot close signal only)
|
|
147
|
+
"masons_end_conversation (rare one-shot close signal only), " +
|
|
148
|
+
"masons_status (your canonical identity and participation status). " +
|
|
134
149
|
"Always try these tools first for network operations. " +
|
|
135
150
|
"If a tool call fails, report the error to your user — do not silently work around it. " +
|
|
136
151
|
"You interact with multiple entities simultaneously — your owner and agents on the network. " +
|
|
@@ -147,13 +162,15 @@ const plugin = {
|
|
|
147
162
|
"";
|
|
148
163
|
api.on("before_prompt_build", async (_event, ctx) => {
|
|
149
164
|
const hookCtx = ctx;
|
|
150
|
-
const
|
|
165
|
+
const messageProvider = resolveHookProvider(hookCtx);
|
|
166
|
+
const invocationConversationManager = getInvocationConversationManager();
|
|
151
167
|
const turnIsOwner = consumeCurrentTurnIsOwner();
|
|
152
168
|
const turnOwnerSignal = consumeCurrentTurnOwnerSignal();
|
|
153
|
-
const turnSender = consumeCurrentTurnSender();
|
|
154
|
-
const turnSenderAddress = consumeCurrentTurnSenderAddress();
|
|
155
169
|
const servicesRetainedReply = isServicesRetainedReplyContext();
|
|
156
|
-
|
|
170
|
+
const turnSenderAddress = invocationConversationManager
|
|
171
|
+
? resolveHookSender(hookCtx, servicesRetainedReply)
|
|
172
|
+
: null;
|
|
173
|
+
setCurrentTurnChannelId(messageProvider ?? null);
|
|
157
174
|
setCurrentTurnIsOwnerForTools(turnIsOwner);
|
|
158
175
|
setCurrentTurnOwnerSignalForTools(turnOwnerSignal);
|
|
159
176
|
const currentGeneration = getStateCacheGeneration();
|
|
@@ -203,7 +220,7 @@ const plugin = {
|
|
|
203
220
|
state.hasCredentials &&
|
|
204
221
|
!state.needsProfile &&
|
|
205
222
|
!state.pendingTarget) {
|
|
206
|
-
if (
|
|
223
|
+
if (messageProvider === "agent-network") {
|
|
207
224
|
if (turnIsOwner) {
|
|
208
225
|
dynamicContext =
|
|
209
226
|
"[Agent Network — Owner via Passport] Your owner (Principal) is talking to you " +
|
|
@@ -226,12 +243,12 @@ const plugin = {
|
|
|
226
243
|
"on the agent network. Your text reply will be sent to that sender — " +
|
|
227
244
|
"your owner (Principal) will NOT see it. To report something to your owner, " +
|
|
228
245
|
"call masons_note_for_owner.";
|
|
229
|
-
const interactionCtx = buildInteractionContext(
|
|
246
|
+
const interactionCtx = buildInteractionContext(messageProvider, turnSenderAddress, invocationConversationManager);
|
|
230
247
|
if (interactionCtx) {
|
|
231
248
|
dynamicContext += `\n\n${interactionCtx}`;
|
|
232
249
|
}
|
|
233
|
-
if (
|
|
234
|
-
const sentMsgs =
|
|
250
|
+
if (turnSenderAddress && invocationConversationManager) {
|
|
251
|
+
const sentMsgs = invocationConversationManager?.getRecentOutboundContext(turnSenderAddress) ?? [];
|
|
235
252
|
if (sentMsgs.length > 0) {
|
|
236
253
|
const lines = sentMsgs.map((m) => {
|
|
237
254
|
const preview = m.content.length > 500
|
|
@@ -240,7 +257,7 @@ const plugin = {
|
|
|
240
257
|
return `• (${formatTimeAgo(m.timestamp)}): "${preview}"`;
|
|
241
258
|
});
|
|
242
259
|
dynamicContext +=
|
|
243
|
-
`\n\n[Your recent messages to ${
|
|
260
|
+
`\n\n[Your recent messages to ${renderPeer(turnSenderAddress, invocationConversationManager)}]\n` +
|
|
244
261
|
lines.join("\n");
|
|
245
262
|
}
|
|
246
263
|
}
|
|
@@ -261,7 +278,7 @@ const plugin = {
|
|
|
261
278
|
? `${dynamicContext}\n\n${nudge}`
|
|
262
279
|
: nudge;
|
|
263
280
|
}
|
|
264
|
-
const interactionCtx = buildInteractionContext(
|
|
281
|
+
const interactionCtx = buildInteractionContext(messageProvider, null);
|
|
265
282
|
if (interactionCtx) {
|
|
266
283
|
dynamicContext = dynamicContext
|
|
267
284
|
? `${dynamicContext}\n\n${interactionCtx}`
|
|
@@ -287,10 +304,12 @@ const plugin = {
|
|
|
287
304
|
if (state.hasCredentials) {
|
|
288
305
|
const envAgent = getAgentIdentity();
|
|
289
306
|
if (envAgent) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
identityLine
|
|
307
|
+
const registered = envAgent.name
|
|
308
|
+
? `@${envAgent.handle}(${envAgent.name})`
|
|
309
|
+
: `@${envAgent.handle}`;
|
|
310
|
+
const identityLine = `[Identity] The Gateway registered this connection as ${registered}. ` +
|
|
311
|
+
"This is connection-level context, not your canonical network identity — " +
|
|
312
|
+
"for the canonical answer, call masons_status.";
|
|
294
313
|
dynamicContext = dynamicContext
|
|
295
314
|
? `${identityLine}\n\n${dynamicContext}`
|
|
296
315
|
: identityLine;
|
|
@@ -7,9 +7,8 @@ export declare class SentMessageBuffer {
|
|
|
7
7
|
static readonly MAX_PER_CONTACT = 5;
|
|
8
8
|
static readonly TTL_MS: number;
|
|
9
9
|
static readonly MAX_CONTENT_LENGTH = 1000;
|
|
10
|
-
record(
|
|
11
|
-
getRecent(
|
|
10
|
+
record(peerAddress: string, content: string): void;
|
|
11
|
+
getRecent(peerAddress: string): SentMessage[];
|
|
12
12
|
clear(): void;
|
|
13
13
|
}
|
|
14
|
-
export declare const sentMessageBuffer: SentMessageBuffer;
|
|
15
14
|
//# sourceMappingURL=sent-message-buffer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sent-message-buffer.d.ts","sourceRoot":"","sources":["../src/sent-message-buffer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sent-message-buffer.d.ts","sourceRoot":"","sources":["../src/sent-message-buffer.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,WAAW;IAE1B,OAAO,EAAE,MAAM,CAAC;IAEhB,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAoC;IAGnD,MAAM,CAAC,QAAQ,CAAC,eAAe,KAAK;IAEpC,MAAM,CAAC,QAAQ,CAAC,MAAM,SAAsB;IAE5C,MAAM,CAAC,QAAQ,CAAC,kBAAkB,QAAQ;IAM1C,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAgClD,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE;IAsB7C,KAAK,IAAI,IAAI;CAGd"}
|