@gethmy/mcp 2.3.1 → 2.3.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/dist/lib/active-learning.js +939 -787
- package/dist/lib/api-client.js +2527 -644
- package/dist/lib/auto-session.js +177 -196
- package/dist/lib/cli.js +34954 -128
- package/dist/lib/config.js +235 -201
- package/dist/lib/consolidation.js +374 -289
- package/dist/lib/context-assembly.js +1265 -838
- package/dist/lib/graph-expansion.js +139 -155
- package/dist/lib/http.js +1917 -130
- package/dist/lib/index.js +29525 -5
- package/dist/lib/lifecycle-maintenance.js +663 -79
- package/dist/lib/memory-cleanup.js +1315 -409
- package/dist/lib/onboard.js +2588 -32
- package/dist/lib/prompt-builder.js +438 -445
- package/dist/lib/remote.js +31733 -143
- package/dist/lib/server.js +29388 -3229
- package/dist/lib/skills.js +315 -132
- package/dist/lib/tui/agents.js +128 -107
- package/dist/lib/tui/docs.js +1590 -687
- package/dist/lib/tui/setup.js +5698 -804
- package/dist/lib/tui/theme.js +183 -86
- package/dist/lib/tui/writer.js +1149 -176
- package/package.json +2 -2
- package/src/memory-cleanup.ts +2 -4
- package/dist/lib/__tests__/active-learning.test.js +0 -386
- package/dist/lib/__tests__/agent-performance-profiles.test.js +0 -325
- package/dist/lib/__tests__/auto-session.test.js +0 -661
- package/dist/lib/__tests__/context-assembly.test.js +0 -362
- package/dist/lib/__tests__/graph-expansion.test.js +0 -150
- package/dist/lib/__tests__/integration-memory-crud.test.js +0 -797
- package/dist/lib/__tests__/integration-memory-system.test.js +0 -281
- package/dist/lib/__tests__/lifecycle-maintenance.test.js +0 -207
- package/dist/lib/__tests__/pattern-detection.test.js +0 -295
- package/dist/lib/__tests__/prompt-builder.test.js +0 -418
|
@@ -1,163 +1,147 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
candidates = retry.entities
|
|
35
|
-
.filter((e) => e.id !== entityId)
|
|
36
|
-
.slice(0, maxRelations);
|
|
37
|
-
}
|
|
38
|
-
let relationsCreated = 0;
|
|
39
|
-
for (const candidate of candidates) {
|
|
40
|
-
try {
|
|
41
|
-
await client.createMemoryRelation({
|
|
42
|
-
source_id: entityId,
|
|
43
|
-
target_id: candidate.id,
|
|
44
|
-
relation_type: "relates_to",
|
|
45
|
-
confidence: 0.6,
|
|
46
|
-
});
|
|
47
|
-
relationsCreated++;
|
|
48
|
-
}
|
|
49
|
-
catch (err) {
|
|
50
|
-
// Silently skip 409 Conflict (relation already exists) and other errors
|
|
51
|
-
const status = err?.status;
|
|
52
|
-
if (status !== 409) {
|
|
53
|
-
// Non-409 errors are still non-fatal; just skip
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return { relationsCreated };
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
// Never block callers due to graph expansion failures
|
|
61
|
-
return { relationsCreated: 0 };
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Find entities semantically similar to the given title+content using
|
|
66
|
-
* hybrid FTS+vector search. Returns entities sorted by relevance.
|
|
67
|
-
*/
|
|
68
|
-
export async function findSimilarEntities(client, title, content, workspaceId, options) {
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
19
|
+
var __export = (target, all) => {
|
|
20
|
+
for (var name in all)
|
|
21
|
+
__defProp(target, name, {
|
|
22
|
+
get: all[name],
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
set: (newValue) => all[name] = () => newValue
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
29
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
30
|
+
|
|
31
|
+
// src/graph-expansion.ts
|
|
32
|
+
async function autoExpandGraph(client, entityId, title, content, _tags, workspaceId, projectId, maxRelations = 5) {
|
|
33
|
+
try {
|
|
69
34
|
const contentSnippet = content.slice(0, 200).trim();
|
|
70
35
|
const query = [title, contentSnippet].filter(Boolean).join(" ");
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return true;
|
|
85
|
-
});
|
|
36
|
+
let candidates = [];
|
|
37
|
+
const { entities } = await client.searchMemoryEntities(workspaceId, query, {
|
|
38
|
+
project_id: projectId,
|
|
39
|
+
limit: 20
|
|
40
|
+
});
|
|
41
|
+
candidates = entities.filter((e) => e.id !== entityId).slice(0, maxRelations);
|
|
42
|
+
if (candidates.length === 0) {
|
|
43
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
44
|
+
const retry = await client.searchMemoryEntities(workspaceId, query, {
|
|
45
|
+
project_id: projectId,
|
|
46
|
+
limit: 20
|
|
47
|
+
});
|
|
48
|
+
candidates = retry.entities.filter((e) => e.id !== entityId).slice(0, maxRelations);
|
|
86
49
|
}
|
|
87
|
-
|
|
88
|
-
|
|
50
|
+
let relationsCreated = 0;
|
|
51
|
+
for (const candidate of candidates) {
|
|
52
|
+
try {
|
|
53
|
+
await client.createMemoryRelation({
|
|
54
|
+
source_id: entityId,
|
|
55
|
+
target_id: candidate.id,
|
|
56
|
+
relation_type: "relates_to",
|
|
57
|
+
confidence: 0.6
|
|
58
|
+
});
|
|
59
|
+
relationsCreated++;
|
|
60
|
+
} catch (err) {
|
|
61
|
+
const status = err?.status;
|
|
62
|
+
if (status !== 409) {}
|
|
63
|
+
}
|
|
89
64
|
}
|
|
65
|
+
return { relationsCreated };
|
|
66
|
+
} catch {
|
|
67
|
+
return { relationsCreated: 0 };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async function findSimilarEntities(client, title, content, workspaceId, options) {
|
|
71
|
+
const contentSnippet = content.slice(0, 200).trim();
|
|
72
|
+
const query = [title, contentSnippet].filter(Boolean).join(" ");
|
|
73
|
+
try {
|
|
74
|
+
const { entities } = await client.searchMemoryEntities(workspaceId, query, {
|
|
75
|
+
project_id: options?.projectId,
|
|
76
|
+
limit: options?.limit ?? 20,
|
|
77
|
+
type: options?.type
|
|
78
|
+
});
|
|
79
|
+
const minScore = options?.minRrfScore ?? 0;
|
|
80
|
+
const excludeSet = new Set(options?.excludeIds || []);
|
|
81
|
+
return entities.filter((e) => {
|
|
82
|
+
if (excludeSet.has(e.id))
|
|
83
|
+
return false;
|
|
84
|
+
if (minScore > 0 && (e.rrf_score ?? 0) < minScore)
|
|
85
|
+
return false;
|
|
86
|
+
return true;
|
|
87
|
+
});
|
|
88
|
+
} catch {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
90
91
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
sourceType: "lesson",
|
|
113
|
-
targetType: "error",
|
|
114
|
-
relation: "learned_from",
|
|
115
|
-
direction: "forward",
|
|
116
|
-
},
|
|
92
|
+
var CAUSAL_LOOKUP = [
|
|
93
|
+
{
|
|
94
|
+
sourceType: "error",
|
|
95
|
+
targetType: "solution",
|
|
96
|
+
relation: "resolved_by",
|
|
97
|
+
direction: "forward"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
sourceType: "solution",
|
|
101
|
+
targetType: "error",
|
|
102
|
+
relation: "resolved_by",
|
|
103
|
+
direction: "reverse"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
sourceType: "lesson",
|
|
107
|
+
targetType: "error",
|
|
108
|
+
relation: "learned_from",
|
|
109
|
+
direction: "forward"
|
|
110
|
+
}
|
|
117
111
|
];
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
112
|
+
async function linkCrossTypeNeighbors(client, entityId, entityType, title, content, workspaceId, projectId) {
|
|
113
|
+
const rules = CAUSAL_LOOKUP.filter((r) => r.sourceType === entityType);
|
|
114
|
+
if (rules.length === 0)
|
|
115
|
+
return { relationsCreated: 0 };
|
|
116
|
+
let relationsCreated = 0;
|
|
117
|
+
for (const rule of rules) {
|
|
118
|
+
try {
|
|
119
|
+
const matches = await findSimilarEntities(client, title, content, workspaceId, {
|
|
120
|
+
projectId,
|
|
121
|
+
limit: 10,
|
|
122
|
+
minRrfScore: 0.04,
|
|
123
|
+
excludeIds: [entityId],
|
|
124
|
+
type: rule.targetType
|
|
125
|
+
});
|
|
126
|
+
for (const match of matches.slice(0, 3)) {
|
|
127
|
+
const sourceId = rule.direction === "forward" ? entityId : match.id;
|
|
128
|
+
const targetId = rule.direction === "forward" ? match.id : entityId;
|
|
132
129
|
try {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
await client.createMemoryRelation({
|
|
146
|
-
source_id: sourceId,
|
|
147
|
-
target_id: targetId,
|
|
148
|
-
relation_type: rule.relation,
|
|
149
|
-
confidence: 0.65,
|
|
150
|
-
});
|
|
151
|
-
relationsCreated++;
|
|
152
|
-
}
|
|
153
|
-
catch {
|
|
154
|
-
// Skip duplicate/failed relations silently
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
catch {
|
|
159
|
-
// Non-fatal: search failure for one rule shouldn't block others
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
return { relationsCreated };
|
|
130
|
+
await client.createMemoryRelation({
|
|
131
|
+
source_id: sourceId,
|
|
132
|
+
target_id: targetId,
|
|
133
|
+
relation_type: rule.relation,
|
|
134
|
+
confidence: 0.65
|
|
135
|
+
});
|
|
136
|
+
relationsCreated++;
|
|
137
|
+
} catch {}
|
|
138
|
+
}
|
|
139
|
+
} catch {}
|
|
140
|
+
}
|
|
141
|
+
return { relationsCreated };
|
|
163
142
|
}
|
|
143
|
+
export {
|
|
144
|
+
linkCrossTypeNeighbors,
|
|
145
|
+
findSimilarEntities,
|
|
146
|
+
autoExpandGraph
|
|
147
|
+
};
|