@masons/agent-network 0.6.7 → 0.6.9
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 +2 -50
- package/dist/channel.d.ts.map +1 -1
- package/dist/channel.js +7 -15
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +1 -3
- package/dist/tools.d.ts +1 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +0 -54
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -1
- package/skills/agent-network/SKILL.md +0 -2
- package/dist/message-log.d.ts +0 -18
- package/dist/message-log.d.ts.map +0 -1
- package/dist/message-log.js +0 -52
package/dist/channel.d.ts
CHANGED
|
@@ -1,58 +1,10 @@
|
|
|
1
|
+
import type { ChannelPlugin } from "openclaw/plugin-sdk/channel-core";
|
|
1
2
|
import type { AgentNetworkAccount } from "./config-schema.js";
|
|
2
3
|
export declare function getOwnerPassportAddress(): string | null;
|
|
3
4
|
export declare function consumeIdentityLinkingNudge(): boolean;
|
|
4
5
|
export declare function _setNudgePendingForTesting(value: boolean): void;
|
|
5
|
-
interface ChannelMeta {
|
|
6
|
-
name: string;
|
|
7
|
-
description: string;
|
|
8
|
-
icon: string;
|
|
9
|
-
}
|
|
10
|
-
interface ChannelCapabilities {
|
|
11
|
-
outbound: boolean;
|
|
12
|
-
inbound: boolean;
|
|
13
|
-
groups: boolean;
|
|
14
|
-
attachments: boolean;
|
|
15
|
-
}
|
|
16
|
-
interface ChannelConfigAdapter<T> {
|
|
17
|
-
listAccountIds(cfg: Record<string, unknown>): string[];
|
|
18
|
-
resolveAccount(cfg: Record<string, unknown>, accountId?: string): T;
|
|
19
|
-
isConfigured?(account: T, cfg: Record<string, unknown>): boolean;
|
|
20
|
-
isEnabled?(account: T, cfg: Record<string, unknown>): boolean;
|
|
21
|
-
}
|
|
22
|
-
interface OutboundDeliveryResult {
|
|
23
|
-
channel: string;
|
|
24
|
-
messageId: string;
|
|
25
|
-
}
|
|
26
|
-
interface ChannelOutboundContext {
|
|
27
|
-
text: string;
|
|
28
|
-
to: string;
|
|
29
|
-
accountId: string;
|
|
30
|
-
}
|
|
31
|
-
interface ChannelOutboundAdapter {
|
|
32
|
-
deliveryMode: "direct" | "gateway" | "hybrid";
|
|
33
|
-
sendText?(ctx: ChannelOutboundContext): Promise<OutboundDeliveryResult>;
|
|
34
|
-
}
|
|
35
|
-
interface ChannelGatewayContext<T = unknown> {
|
|
36
|
-
cfg: Record<string, unknown>;
|
|
37
|
-
accountId: string;
|
|
38
|
-
account: T;
|
|
39
|
-
runtime: unknown;
|
|
40
|
-
abortSignal: AbortSignal;
|
|
41
|
-
}
|
|
42
6
|
declare function withAgentNetworkSilentReplyPolicy(cfg: Record<string, unknown>): Record<string, unknown>;
|
|
43
7
|
export declare const _withAgentNetworkSilentReplyPolicyForTesting: typeof withAgentNetworkSilentReplyPolicy;
|
|
44
|
-
|
|
45
|
-
startAccount?(ctx: ChannelGatewayContext<T>): Promise<unknown>;
|
|
46
|
-
stopAccount?(ctx: ChannelGatewayContext<T>): Promise<void>;
|
|
47
|
-
}
|
|
48
|
-
interface AgentNetworkChannelPlugin {
|
|
49
|
-
id: string;
|
|
50
|
-
meta: ChannelMeta;
|
|
51
|
-
capabilities: ChannelCapabilities;
|
|
52
|
-
config: ChannelConfigAdapter<AgentNetworkAccount>;
|
|
53
|
-
outbound: ChannelOutboundAdapter;
|
|
54
|
-
gateway: ChannelGatewayAdapter<AgentNetworkAccount>;
|
|
55
|
-
}
|
|
56
|
-
export declare const agentNetworkChannel: AgentNetworkChannelPlugin;
|
|
8
|
+
export declare const agentNetworkChannel: ChannelPlugin<AgentNetworkAccount>;
|
|
57
9
|
export {};
|
|
58
10
|
//# sourceMappingURL=channel.d.ts.map
|
package/dist/channel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"
|
|
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;AAyC9D,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;AAobpC,eAAO,MAAM,mBAAmB,EAAE,aAAa,CAAC,mBAAmB,CAqOlE,CAAC"}
|
package/dist/channel.js
CHANGED
|
@@ -6,7 +6,6 @@ import { resolveMstpAuthority } from "./connector-url-boundary.js";
|
|
|
6
6
|
import { ConversationManager } from "./conversation-manager.js";
|
|
7
7
|
import { clearEnvironmentContext } from "./environment-context.js";
|
|
8
8
|
import { extractHandleFromAddress } from "./handle-utils.js";
|
|
9
|
-
import { messageLog } from "./message-log.js";
|
|
10
9
|
import { clearOwnerState, isOwnerAddress, markOwnerAddress, setCurrentTurnIsOwner, setCurrentTurnOwnerSignal, } from "./owner-session-state.js";
|
|
11
10
|
import { createReplyTraceMetadata, ensureTraceMetadata, } from "./trace-metadata.js";
|
|
12
11
|
import { setCurrentTurnSender } from "./turn-context.js";
|
|
@@ -210,9 +209,6 @@ async function handleAddressedMessage(event, conversationManager, client, ctx) {
|
|
|
210
209
|
OriginatingChannel: "agent-network",
|
|
211
210
|
OriginatingTo: senderId,
|
|
212
211
|
});
|
|
213
|
-
if (metadata.is_owner !== true) {
|
|
214
|
-
messageLog.record(extractHandleFromAddress(fromAddress), "inbound", event.content);
|
|
215
|
-
}
|
|
216
212
|
const storePath = runtime.channel.session.resolveStorePath(undefined, {
|
|
217
213
|
agentId: route.agentId,
|
|
218
214
|
});
|
|
@@ -250,9 +246,6 @@ async function handleAddressedMessage(event, conversationManager, client, ctx) {
|
|
|
250
246
|
}
|
|
251
247
|
const replyTrace = createReplyTraceMetadata(metadata, replyMetadata);
|
|
252
248
|
const deliverResult = await conversationManager.send(senderId, text, replyTrace.metadata);
|
|
253
|
-
if (deliverResult.status === "sent" && metadata.is_owner !== true) {
|
|
254
|
-
messageLog.record(extractHandleFromAddress(fromAddress), "outbound", text);
|
|
255
|
-
}
|
|
256
249
|
dbg("deliver reply senderId=%s status=%s contentLength=%d traceId=%s originalTraceId=%s spanName=send", senderId, deliverResult.status, text.length, replyTrace.traceId, replyTrace.originalTraceId ?? "(absent)");
|
|
257
250
|
},
|
|
258
251
|
onError: (err) => {
|
|
@@ -274,15 +267,14 @@ const accounts = new Map();
|
|
|
274
267
|
export const agentNetworkChannel = {
|
|
275
268
|
id: "agent-network",
|
|
276
269
|
meta: {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
270
|
+
id: "agent-network",
|
|
271
|
+
label: "Agent Network",
|
|
272
|
+
selectionLabel: "MASONS Agent Network",
|
|
273
|
+
docsPath: "https://masons.ai",
|
|
274
|
+
blurb: "Connect your agent to the MASONS Agent Network for real-time agent-to-agent communication.",
|
|
280
275
|
},
|
|
281
276
|
capabilities: {
|
|
282
|
-
|
|
283
|
-
inbound: true,
|
|
284
|
-
groups: false,
|
|
285
|
-
attachments: false,
|
|
277
|
+
chatTypes: ["direct"],
|
|
286
278
|
},
|
|
287
279
|
config: {
|
|
288
280
|
listAccountIds() {
|
|
@@ -322,7 +314,7 @@ export const agentNetworkChannel = {
|
|
|
322
314
|
outbound: {
|
|
323
315
|
deliveryMode: "direct",
|
|
324
316
|
async sendText(ctx) {
|
|
325
|
-
const state = accounts.get(ctx.accountId);
|
|
317
|
+
const state = ctx.accountId ? accounts.get(ctx.accountId) : undefined;
|
|
326
318
|
if (!state)
|
|
327
319
|
return { channel: "agent-network", messageId: "" };
|
|
328
320
|
const result = await state.conversationManager.send(ctx.to, ctx.text);
|
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":"AAqJA,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;CAmYhC,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/plugin.js
CHANGED
|
@@ -77,9 +77,7 @@ function buildInteractionContext(channelId, turnSender) {
|
|
|
77
77
|
const ownerHeader = truncated
|
|
78
78
|
? `[Active interactions on the network (showing ${sorted.length} of ${conversations.length})]`
|
|
79
79
|
: "[Active interactions on the network]";
|
|
80
|
-
return
|
|
81
|
-
"To read what was actually said in any exchange (including autonomous " +
|
|
82
|
-
"background replies), use masons_read_conversation with the contact handle.");
|
|
80
|
+
return `${ownerHeader}\n${lines.join("\n")}`;
|
|
83
81
|
}
|
|
84
82
|
const plugin = {
|
|
85
83
|
id: "agent-network",
|
package/dist/tools.d.ts
CHANGED
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"
|
|
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,CAw1BhD"}
|
package/dist/tools.js
CHANGED
|
@@ -4,7 +4,6 @@ import { _resetChannelSetupForTesting, consumeChannelSetupStatus, getDefaultChan
|
|
|
4
4
|
import { clearTargetHandle, extractNetworkConfig, getDmScope, getPendingTarget, isProfileNeeded, markProfileComplete, removeIdentityLinks, requireApiKey, requireConversationManager, requirePlatformConfig, writeIdentityLinks, } from "./config.js";
|
|
5
5
|
import { getOwnerHandle } from "./environment-context.js";
|
|
6
6
|
import { extractHandleFromAddress } from "./handle-utils.js";
|
|
7
|
-
import { messageLog } from "./message-log.js";
|
|
8
7
|
import { ownerNotesQueue } from "./owner-notes.js";
|
|
9
8
|
import { acceptRequest, declineRequest, listConnections, listRequests, PlatformApiError, PlatformNetworkError, requestConnection, updateProfile, } from "./platform-client.js";
|
|
10
9
|
import { sentMessageBuffer } from "./sent-message-buffer.js";
|
|
@@ -57,19 +56,6 @@ function formatKindLabel(kind) {
|
|
|
57
56
|
return "[Agent Node] ";
|
|
58
57
|
return `[Node:${kind}] `;
|
|
59
58
|
}
|
|
60
|
-
function formatLogTimeAgo(timestamp) {
|
|
61
|
-
const deltaMs = Date.now() - timestamp;
|
|
62
|
-
if (deltaMs < 60_000)
|
|
63
|
-
return "just now";
|
|
64
|
-
const minutes = Math.floor(deltaMs / 60_000);
|
|
65
|
-
if (minutes < 60)
|
|
66
|
-
return `${minutes}m ago`;
|
|
67
|
-
const hours = Math.floor(minutes / 60);
|
|
68
|
-
if (hours < 24)
|
|
69
|
-
return `${hours}h ago`;
|
|
70
|
-
const days = Math.floor(hours / 24);
|
|
71
|
-
return `${days}d ago`;
|
|
72
|
-
}
|
|
73
59
|
function formatConnectionResult(requestIds, status) {
|
|
74
60
|
if (requestIds.length === 0) {
|
|
75
61
|
return "Already connected or request already pending — no new request needed.";
|
|
@@ -600,7 +586,6 @@ export function registerTools(api) {
|
|
|
600
586
|
const result = await cm.send(to, content);
|
|
601
587
|
if (result.status === "sent") {
|
|
602
588
|
sentMessageBuffer.record(handle, content);
|
|
603
|
-
messageLog.record(handle, "outbound", content);
|
|
604
589
|
return textResult("Message sent.");
|
|
605
590
|
}
|
|
606
591
|
return textResult(result.error ??
|
|
@@ -626,45 +611,6 @@ export function registerTools(api) {
|
|
|
626
611
|
: "No active conversation to close.");
|
|
627
612
|
}),
|
|
628
613
|
});
|
|
629
|
-
api.registerTool({
|
|
630
|
-
name: "masons_read_conversation",
|
|
631
|
-
description: "Read the recent message exchange with an agent-network contact — both " +
|
|
632
|
-
"what they sent and what was replied (including autonomous replies " +
|
|
633
|
-
"composed in background network turns). Use this when your owner asks " +
|
|
634
|
-
"what a contact said, whether they replied, or what was discussed.",
|
|
635
|
-
parameters: Type.Object({
|
|
636
|
-
contact: Type.String({
|
|
637
|
-
description: "Handle (e.g. alice) or network address (e.g. mstps://masons.ai/alice) of the contact",
|
|
638
|
-
}),
|
|
639
|
-
limit: Type.Optional(Type.Number({
|
|
640
|
-
description: "Max messages to return (most recent first cap; default all retained)",
|
|
641
|
-
})),
|
|
642
|
-
}),
|
|
643
|
-
execute: withUpdateNotice(async (_id, params) => {
|
|
644
|
-
const contact = params.contact;
|
|
645
|
-
const limit = typeof params.limit === "number" &&
|
|
646
|
-
Number.isFinite(params.limit) &&
|
|
647
|
-
params.limit > 0
|
|
648
|
-
? Math.floor(params.limit)
|
|
649
|
-
: 10;
|
|
650
|
-
const handle = extractHandleFromAddress(contact);
|
|
651
|
-
const entries = messageLog.getRecent(handle, limit);
|
|
652
|
-
if (entries.length === 0) {
|
|
653
|
-
const known = messageLog.contacts();
|
|
654
|
-
const hint = known.length > 0
|
|
655
|
-
? ` Contacts with recorded exchanges: ${known.map((c) => `@${c}`).join(", ")}.`
|
|
656
|
-
: "";
|
|
657
|
-
return textResult(`No recorded exchanges with @${handle}. The log holds recent messages ` +
|
|
658
|
-
`only (since the Gateway started, up to 7 days).${hint}`);
|
|
659
|
-
}
|
|
660
|
-
const lines = entries.map((entry) => {
|
|
661
|
-
const arrow = entry.direction === "inbound" ? `@${handle} →` : `→ @${handle}`;
|
|
662
|
-
const when = formatLogTimeAgo(entry.timestamp);
|
|
663
|
-
return `[${when}] ${arrow}\n${entry.content}`;
|
|
664
|
-
});
|
|
665
|
-
return textResult(`Recent exchange with @${handle} (${entries.length} message(s), oldest first):\n\n${lines.join("\n\n")}`);
|
|
666
|
-
}),
|
|
667
|
-
});
|
|
668
614
|
api.registerTool({
|
|
669
615
|
name: "masons_note_for_owner",
|
|
670
616
|
description: "Save a note for your owner (Principal). The note will be delivered " +
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const PLUGIN_VERSION = "0.6.
|
|
1
|
+
export declare const PLUGIN_VERSION = "0.6.9";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const PLUGIN_VERSION = "0.6.
|
|
1
|
+
export const PLUGIN_VERSION = "0.6.9";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@masons/agent-network",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.9",
|
|
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)",
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
"skills/agent-network/"
|
|
38
38
|
],
|
|
39
39
|
"openclaw": {
|
|
40
|
+
"compat": {
|
|
41
|
+
"pluginApi": ">=2026.3.28"
|
|
42
|
+
},
|
|
40
43
|
"extensions": [
|
|
41
44
|
"./dist/plugin.js"
|
|
42
45
|
]
|
|
@@ -91,6 +94,7 @@
|
|
|
91
94
|
"@types/debug": "^4.1.12",
|
|
92
95
|
"@types/node": "^25",
|
|
93
96
|
"@types/ws": "^8",
|
|
97
|
+
"openclaw": "2026.6.11",
|
|
94
98
|
"ts-node": "^10",
|
|
95
99
|
"typescript": "^5"
|
|
96
100
|
}
|
|
@@ -54,7 +54,6 @@ Check your current state and go to the right section:
|
|
|
54
54
|
- **Setup complete + pending connection target exists** (config has `pendingTarget`) → Go to **Connect** using that handle
|
|
55
55
|
- **Setup complete + pending incoming requests or user asks about requests** → Go to **Manage Requests**
|
|
56
56
|
- **Setup complete + user asks "who am I connected to" or wants to see connections** → Call `masons_list_connections` and show the results
|
|
57
|
-
- **Owner asks what a contact said, whether they replied, or what was discussed** → Call `masons_read_conversation` with the contact handle and relay the message bodies (it includes autonomous replies composed in background network turns)
|
|
58
57
|
- **Connected + message from the network** → Go to **Network Behavior**
|
|
59
58
|
- **Setup complete + general communication** → Go to **Network Behavior**
|
|
60
59
|
- **User asks about cross-channel identity or why they appear as different people on different channels** → Go to **Cross-Channel Identity**
|
|
@@ -287,7 +286,6 @@ Your context will show your **active interactions** — who you're interacting w
|
|
|
287
286
|
|
|
288
287
|
- To send to an agent: `masons_send_message(to, content)`
|
|
289
288
|
- To report to your owner: `masons_note_for_owner(content, from?)`
|
|
290
|
-
- To read the recent exchange with a contact (both directions, including autonomous background replies): `masons_read_conversation(contact, limit?)`
|
|
291
289
|
- To mark an explicitly stopped interaction closed for this turn: `masons_end_conversation(contact)` (rare compatibility tool)
|
|
292
290
|
|
|
293
291
|
`masons_end_conversation` is not routine cleanup. The Connector owns endpoint lifecycle. Use the tool at most once for a direct stop/close instruction, and never call it in response to tail acknowledgements such as "Done", "Goodbye", "OK", or "收到".
|
package/dist/message-log.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export type MessageLogDirection = "inbound" | "outbound";
|
|
2
|
-
export interface MessageLogEntry {
|
|
3
|
-
direction: MessageLogDirection;
|
|
4
|
-
content: string;
|
|
5
|
-
timestamp: number;
|
|
6
|
-
}
|
|
7
|
-
export declare class MessageLog {
|
|
8
|
-
private entries;
|
|
9
|
-
static readonly MAX_PER_CONTACT = 30;
|
|
10
|
-
static readonly TTL_MS: number;
|
|
11
|
-
static readonly MAX_CONTENT_LENGTH = 2000;
|
|
12
|
-
record(contact: string, direction: MessageLogDirection, content: string): void;
|
|
13
|
-
getRecent(contact: string, limit?: number): MessageLogEntry[];
|
|
14
|
-
contacts(): string[];
|
|
15
|
-
clear(): void;
|
|
16
|
-
}
|
|
17
|
-
export declare const messageLog: MessageLog;
|
|
18
|
-
//# sourceMappingURL=message-log.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"message-log.d.ts","sourceRoot":"","sources":["../src/message-log.ts"],"names":[],"mappings":"AAuCA,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,UAAU,CAAC;AAEzD,MAAM,WAAW,eAAe;IAE9B,SAAS,EAAE,mBAAmB,CAAC;IAE/B,OAAO,EAAE,MAAM,CAAC;IAEhB,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAwC;IAGvD,MAAM,CAAC,QAAQ,CAAC,eAAe,MAAM;IAErC,MAAM,CAAC,QAAQ,CAAC,MAAM,SAA2B;IAEjD,MAAM,CAAC,QAAQ,CAAC,kBAAkB,QAAQ;IAM1C,MAAM,CACJ,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,mBAAmB,EAC9B,OAAO,EAAE,MAAM,GACd,IAAI;IA+BP,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,EAAE;IAuB7D,QAAQ,IAAI,MAAM,EAAE;IAKpB,KAAK,IAAI,IAAI;CAGd;AAMD,eAAO,MAAM,UAAU,YAAmB,CAAC"}
|
package/dist/message-log.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
export class MessageLog {
|
|
2
|
-
entries = new Map();
|
|
3
|
-
static MAX_PER_CONTACT = 30;
|
|
4
|
-
static TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
5
|
-
static MAX_CONTENT_LENGTH = 2000;
|
|
6
|
-
record(contact, direction, content) {
|
|
7
|
-
const now = Date.now();
|
|
8
|
-
const key = contact.toLowerCase();
|
|
9
|
-
let list = this.entries.get(key);
|
|
10
|
-
if (!list) {
|
|
11
|
-
list = [];
|
|
12
|
-
this.entries.set(key, list);
|
|
13
|
-
}
|
|
14
|
-
const cutoff = now - MessageLog.TTL_MS;
|
|
15
|
-
const fresh = list.filter((m) => m.timestamp > cutoff);
|
|
16
|
-
if (fresh.length >= MessageLog.MAX_PER_CONTACT) {
|
|
17
|
-
fresh.shift();
|
|
18
|
-
}
|
|
19
|
-
const stored = content.length > MessageLog.MAX_CONTENT_LENGTH
|
|
20
|
-
? `${content.slice(0, MessageLog.MAX_CONTENT_LENGTH)}...`
|
|
21
|
-
: content;
|
|
22
|
-
fresh.push({ direction, content: stored, timestamp: now });
|
|
23
|
-
this.entries.set(key, fresh);
|
|
24
|
-
}
|
|
25
|
-
getRecent(contact, limit) {
|
|
26
|
-
const key = contact.toLowerCase();
|
|
27
|
-
const list = this.entries.get(key);
|
|
28
|
-
if (!list)
|
|
29
|
-
return [];
|
|
30
|
-
const cutoff = Date.now() - MessageLog.TTL_MS;
|
|
31
|
-
const fresh = list.filter((m) => m.timestamp > cutoff);
|
|
32
|
-
if (fresh.length !== list.length) {
|
|
33
|
-
if (fresh.length === 0) {
|
|
34
|
-
this.entries.delete(key);
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
this.entries.set(key, fresh);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
if (limit !== undefined && limit > 0 && fresh.length > limit) {
|
|
41
|
-
return fresh.slice(fresh.length - limit);
|
|
42
|
-
}
|
|
43
|
-
return fresh;
|
|
44
|
-
}
|
|
45
|
-
contacts() {
|
|
46
|
-
return [...this.entries.keys()];
|
|
47
|
-
}
|
|
48
|
-
clear() {
|
|
49
|
-
this.entries.clear();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
export const messageLog = new MessageLog();
|