memtap 4.0.0 → 4.0.2
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/index.ts +55 -16
- package/openclaw.plugin.json +9 -5
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -2027,19 +2027,59 @@ ${memoryContext}
|
|
|
2027
2027
|
);
|
|
2028
2028
|
|
|
2029
2029
|
// ── Hook: Server-Side Capture (message_completed) ──────────────────────────
|
|
2030
|
-
// v4.0.
|
|
2030
|
+
// v4.0.1: Extraction moved to server. Plugin posts user+assistant conversations to /capture.
|
|
2031
|
+
// We buffer user messages per conversation, then capture the pair when the assistant replies.
|
|
2031
2032
|
|
|
2033
|
+
const pendingUserMessages = new Map<string, { content: string; channel?: string; timestamp: string }>();
|
|
2034
|
+
|
|
2035
|
+
// Capture user's inbound message (store for pairing with assistant reply)
|
|
2032
2036
|
api.registerHook(
|
|
2033
|
-
'
|
|
2037
|
+
'message_received',
|
|
2034
2038
|
async (event: any) => {
|
|
2035
2039
|
const cfg = getConfig(api);
|
|
2036
2040
|
if (!cfg.captureEnabled && !cfg.autoCapture) return;
|
|
2037
2041
|
|
|
2038
|
-
const
|
|
2039
|
-
|
|
2040
|
-
if (content
|
|
2042
|
+
const ctx = event || event?.context || {};
|
|
2043
|
+
const content = ctx.content || ctx.bodyForAgent || ctx.body || '';
|
|
2044
|
+
if (!content || typeof content !== 'string') return;
|
|
2045
|
+
if (content === 'NO_REPLY' || content === 'HEARTBEAT_OK') return;
|
|
2041
2046
|
|
|
2042
|
-
const
|
|
2047
|
+
const conversationId = ctx.conversationId || ctx.from || ctx.to || 'default';
|
|
2048
|
+
pendingUserMessages.set(conversationId, {
|
|
2049
|
+
content,
|
|
2050
|
+
channel: ctx.channelId || ctx.provider,
|
|
2051
|
+
timestamp: new Date().toISOString(),
|
|
2052
|
+
});
|
|
2053
|
+
|
|
2054
|
+
// Clean up old pending entries after 10 min
|
|
2055
|
+
setTimeout(() => pendingUserMessages.delete(conversationId), 10 * 60 * 1000);
|
|
2056
|
+
},
|
|
2057
|
+
{
|
|
2058
|
+
name: 'memtap.capture-inbound',
|
|
2059
|
+
description: 'Buffer inbound user messages for capture pairing',
|
|
2060
|
+
}
|
|
2061
|
+
);
|
|
2062
|
+
|
|
2063
|
+
// Capture assistant's outbound reply (pair with buffered user message, then POST to /capture)
|
|
2064
|
+
api.registerHook(
|
|
2065
|
+
'message_sent',
|
|
2066
|
+
async (event: any) => {
|
|
2067
|
+
const cfg = getConfig(api);
|
|
2068
|
+
if (!cfg.captureEnabled && !cfg.autoCapture) return;
|
|
2069
|
+
|
|
2070
|
+
const ctx = event || event?.context || {};
|
|
2071
|
+
const assistantContent = ctx.content || '';
|
|
2072
|
+
if (!assistantContent || typeof assistantContent !== 'string') return;
|
|
2073
|
+
if (assistantContent === 'NO_REPLY' || assistantContent === 'HEARTBEAT_OK') return;
|
|
2074
|
+
if (assistantContent.length < (cfg.captureMinLength || 80)) return;
|
|
2075
|
+
if (ctx.success === false) return;
|
|
2076
|
+
|
|
2077
|
+
const conversationId = ctx.conversationId || ctx.to || ctx.groupId || 'default';
|
|
2078
|
+
const buffered = pendingUserMessages.get(conversationId);
|
|
2079
|
+
const userMessage = buffered?.content;
|
|
2080
|
+
|
|
2081
|
+
// Clear buffer
|
|
2082
|
+
if (buffered) pendingUserMessages.delete(conversationId);
|
|
2043
2083
|
|
|
2044
2084
|
try {
|
|
2045
2085
|
await bbFetch(cfg, `${baseUrl(cfg)}/capture`, {
|
|
@@ -2048,20 +2088,19 @@ ${memoryContext}
|
|
|
2048
2088
|
agent: agentId(cfg, api),
|
|
2049
2089
|
conversation: {
|
|
2050
2090
|
userMessage,
|
|
2051
|
-
assistantMessage:
|
|
2091
|
+
assistantMessage: assistantContent,
|
|
2052
2092
|
context: {
|
|
2053
|
-
channel:
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2093
|
+
channel: ctx.channelId,
|
|
2094
|
+
conversationId,
|
|
2095
|
+
timestamp: new Date().toISOString(),
|
|
2096
|
+
},
|
|
2097
|
+
},
|
|
2098
|
+
}),
|
|
2058
2099
|
});
|
|
2100
|
+
if (cfg.debug) console.log('[memtap] capture posted');
|
|
2059
2101
|
} catch (err) {
|
|
2060
2102
|
// Silent fail — capture is non-critical
|
|
2061
|
-
if (cfg.debug)
|
|
2062
|
-
logger.warn?.(`[memtap] capture failed: ${err}`) ??
|
|
2063
|
-
console.error('[memtap] capture failed:', err);
|
|
2064
|
-
}
|
|
2103
|
+
if (cfg.debug) console.error('[memtap] capture failed:', err);
|
|
2065
2104
|
}
|
|
2066
2105
|
},
|
|
2067
2106
|
{
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"id": "memtap",
|
|
3
3
|
"name": "MemTap",
|
|
4
4
|
"kind": "memory",
|
|
5
|
-
"version": "4.0.
|
|
6
|
-
"description": "Graph-based long-term memory for OpenClaw agents
|
|
5
|
+
"version": "4.0.2",
|
|
6
|
+
"description": "Graph-based long-term memory for OpenClaw agents \u2014 semantic recall, GraphRAG, entity management, decision tracking, neural auto-capture, anomaly detection, consolidation, profiles, and adaptive decay.",
|
|
7
7
|
"defaultConfig": {
|
|
8
8
|
"serverUrl": "https://api.memtap.ai",
|
|
9
9
|
"autoCapture": true,
|
|
@@ -86,12 +86,16 @@
|
|
|
86
86
|
"properties": {
|
|
87
87
|
"include": {
|
|
88
88
|
"type": "array",
|
|
89
|
-
"items": {
|
|
89
|
+
"items": {
|
|
90
|
+
"type": "string"
|
|
91
|
+
},
|
|
90
92
|
"description": "Patterns to prioritize in recall (boost matching memories)"
|
|
91
93
|
},
|
|
92
94
|
"exclude": {
|
|
93
95
|
"type": "array",
|
|
94
|
-
"items": {
|
|
96
|
+
"items": {
|
|
97
|
+
"type": "string"
|
|
98
|
+
},
|
|
95
99
|
"description": "Patterns to exclude from recall results"
|
|
96
100
|
}
|
|
97
101
|
}
|
|
@@ -151,4 +155,4 @@
|
|
|
151
155
|
"helpText": "Include/exclude patterns for memory recall filtering"
|
|
152
156
|
}
|
|
153
157
|
}
|
|
154
|
-
}
|
|
158
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memtap",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2",
|
|
4
4
|
"description": "MemTap — Graph-based long-term memory plugin for OpenClaw agents. Knowledge graph with semantic recall, GraphRAG, entity management, decision tracking, and auto-capture.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openclaw",
|